home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / pas / pasref.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  566.3 KB  |  15,607 lines

  1.  Microsoft(R) Pascal Reference Manual
  2.  
  3.  
  4.  
  5.  ───────────────────────────────────────────────────────────────────────────
  6.  
  7.  
  8.  
  9.  Microsoft(R) Pascal
  10.  
  11.  Reference Manual
  12.  
  13.  
  14.  
  15.  ───────────────────────────────────────────────────────────────────────────
  16.  
  17.  
  18.  
  19.  Information in this document is subject to change without notice and
  20.  does not represent a commitment on the part of Microsoft Corporation. The
  21.  software described in this document is furnished under a license agreement
  22.  or nondisclosure agreement. The software may be used or copied only in
  23.  accordance with the terms of the agreement. It is against the law to copy
  24.  Microsoft Pascal on magnetic tape, disk, or any other medium for any
  25.  purpose other than the purchaser's personal use.
  26.  
  27.  
  28.  
  29.  (C) Copyright Microsoft Corporation, 1981, 1982, 1983, 1984, l985
  30.  
  31.  
  32.  
  33.  If you have comments about the software or these manuals, complete the
  34.  Software Problem Report at the back of the Microsoft Pascal Reference
  35.  Manual and return it to Microsoft Corporation.
  36.  
  37.  
  38.  
  39.  Microsoft and the Microsoft logo are registered trademarks, and MS is a
  40.  trademark of Microsoft Corporation.
  41.  
  42.  CP/M-86 is a  registered trademark, and CP/M-80 is a trademark of Digital
  43.  Research, Inc.
  44.  
  45.  UCSD Pascal is a registered trademark of the Regents of the University of
  46.  California
  47.  
  48.  
  49.  
  50.  Contents
  51.  
  52.  ───────────────────────────────────────────────────────────────────────────
  53.  
  54.  1    Introduction to Microsoft Pascal
  55.  
  56.        1.1  Levels of Microsoft Pascal
  57.        1.2  Selected Features
  58.        1.3  Unimplemented Features
  59.  
  60.  
  61.  2    Language Overview
  62.  
  63.        2.1  Metacommands
  64.        2.2  Programs and Compilable Parts of Programs
  65.        2.3  Procedures and Functions
  66.        2.4  Statements
  67.        2.5  Expressions
  68.        2.6  Variables
  69.        2.7  Constants
  70.        2.8  Identifiers
  71.        2.9  Notation
  72.  
  73.  
  74.  3    Notation
  75.  
  76.        3.1  Components of Identifiers
  77.        3.2  Separators
  78.        3.3  Special Symbols
  79.        3.4  Unused characters
  80.        3.5  Notes on Characters
  81.  
  82.  
  83.  4    Identifiers
  84.  
  85.        4.1  Creating an Identifier
  86.        4.2  Declaring an Identifier
  87.        4.3  The Scope of Identifiers
  88.        4.4  Predeclared Identifiers
  89.  
  90.  
  91.  5    Introduction to Data Types
  92.  
  93.        5.1  What Is a Type?
  94.        5.2  Declaring Data Types
  95.        5.3  Type Compatibility
  96.  
  97.  
  98.  6    Simple Types
  99.  
  100.        6.1  Ordinal Types
  101.        6.2  REAL
  102.        6.3  INTEGER4
  103.  
  104.  
  105.  7    Arrays, Records, and Sets
  106.  
  107.        7.1  Arrays
  108.        7.2  Super Arrays
  109.        7.3  Records
  110.        7.4  Sets
  111.  
  112.  
  113.  8    Files
  114.  
  115.        8.1  Declaring Files
  116.        8.2  The Buffer
  117.        8.3  File Structures
  118.        8.4  File Access Modes
  119.        8.5  The Predelared Files: INPUT and OUTPUT
  120.        8.6  File I/O: Extend Level
  121.        8.7  File I/O: System Level
  122.  
  123.  
  124.  9    Reference and Other Types
  125.  
  126.        9.1  Reference Types
  127.        9.2  PACKED Types
  128.        9.3  Procedural and Functional Types
  129.  
  130.  
  131.  10   Constants
  132.  
  133.        10.1 What Is a Constant?
  134.        10.2 Declaring Constant Identifiers
  135.        10.3 Numeric Constants
  136.        10.4 Character Strings
  137.        10.5 Structured Constants
  138.        10.6 Constant Expressions
  139.  
  140.  
  141.  11   Variables and Values
  142.  
  143.        11.1 What Is a Variable?
  144.        11.2 Declaring a Variable
  145.        11.3 The Value Section
  146.        11.4 Using Variables and Values
  147.        11.5 Attributes
  148.  
  149.  
  150.  12   Expressions
  151.  
  152.        12.1 Simple Type Expressions
  153.        12.2 Boolean Expressions
  154.        12.3 Set Expressions
  155.        12.4 Function Designators
  156.        12.5 Evaluating Expressions
  157.        12.6 Other Features of Expressions
  158.  
  159.  
  160.  13   Statements
  161.  
  162.        13.1 The Syntax of Pascal Statements
  163.        13.2 Simple Statements
  164.        13.3 Structured Statements
  165.  
  166.  
  167.  14   Introduction to Procedures and Functions
  168.  
  169.        14.1 Procedures
  170.        14.2 Functions
  171.        14.3 Attributes and Directives
  172.        14.4 Procedure and Function Parameters
  173.  
  174.  
  175.  15   Available Procedures and Functions
  176.  
  177.        15.1 Categories of Available Procedures and Functions
  178.        15.2 Directory of Functions and Procedures
  179.  
  180.  
  181.  16   File-Oriented Procedures and Functions
  182.  
  183.        16.1 File System Primitive Procedures and Functions
  184.        16.2 Textfile Input and Output
  185.        16.3 Extend Level I/O
  186.  
  187.  
  188.  17   Compilable Parts of a Program
  189.  
  190.        17.1 Programs
  191.        17.2 Modules
  192.        17.3 Units
  193.  
  194.  
  195.  18   Microsoft Pascal Metacommands
  196.  
  197.        18.1 Language Level Setting and Optimization
  198.        18.2 Debugging and Error Handling
  199.        18.3 Source File Control
  200.        18.4 Listing File Control
  201.        18.5 Listing File Format
  202.  
  203.  
  204.  Appendices
  205.  
  206.  A    Pascal Syntax Diagrams
  207.  
  208.  B    Microsoft Pascal Features and the ISO Standard
  209.  
  210.  C    Microsoft Pascal and Other Pascals
  211.  
  212.  D    ASCII Character Codes
  213.  
  214.  E    Summary of Microsoft Pascal Reserved Words
  215.  
  216.  F    Summary of Available Procedures and Functions
  217.  
  218.  G    Summary of Microsoft Pascal Metacommands
  219.  
  220.  
  221.  Figures
  222.  
  223.  Figure 17.1    A Microsoft Pascal Unit
  224.  
  225.  Figure 17.2    Unit with file X.INT
  226.  
  227.  
  228.  Tables
  229.  
  230.  Table 2.1    Summary of Microsoft Pascal Statements
  231.  
  232.  Table 3.1    Summary of Punctuation in Microsoft Pascal
  233.  
  234.  Table 3.2    Equivalent ASCII Characters
  235.  
  236.  Table 4.1    Declaring Identifiers
  237.  
  238.  Table 5.1    Categories of Types in Microsoft Pascal
  239.  
  240.  Table 9.1    Relative and Segmented Machine Addresses
  241.  
  242.  Table 10.1   INTEGER, WORD, and INTEGER4 Constants
  243.  
  244.  Table 10.2   Constant Conversions
  245.  
  246.  Table 10.3   Constant Operators and Functions
  247.  
  248.  Table 11.1   Attributes for Variables
  249.  
  250.  Table 12.1   Expressions
  251.  
  252.  Table 12.2   Set Operators
  253.  
  254.  Table 13.1   Microsoft Pascal Statements
  255.  
  256.  Table 14.1   Attributes and Directives for Procedures and Functions
  257.  
  258.  Table 15.1   Categories of Available Procedures and Functions
  259.  
  260.  Table 15.2   File System Procedures and Functions
  261.  
  262.  Table 15.3   Predeclared Arithmetic Functions
  263.  
  264.  Table 15.4   REAL Functions From the Microsoft FORTRAN Runtime Library
  265.  
  266.  Table 15.5   String Procedures and Functions
  267.  
  268.  Table 16.1   File System Procedures and Functions
  269.  
  270.  Table 16.2   Lazy Evaluation
  271.  
  272.  Table 18.1   Metacommand Notation
  273.  
  274.  Table 18.2   Language and Optimization Level
  275.  
  276.  Table 18.3   Debugging and Error Handling
  277.  
  278.  Table 18.4   Source File Control
  279.  
  280.  Table 18.5   Listing File Control Metacommands
  281.  
  282.  Table C.1    Microsoft Pascal and UCSD Pascal
  283.  
  284.  Table D.1    ASCII Character Codes
  285.  
  286.  Table F.1    Procedures and Functions
  287.  
  288.  Table G.1    Microsoft Pascal Metacommands
  289.  
  290.  
  291.  
  292.  How to Use This Manual
  293.  
  294.  Chapter 1, "Introduction to Microsoft Pascal," introduces the reader to the
  295.  selected and unimplemented features of the Microsoft Pascal language and
  296.  gives a brief overview of the standard, extend, and system levels of
  297.  Microsoft Pascal programming.
  298.  
  299.  Chapter 2, "Language Overview," paints a broad picture of Microsoft Pascal,
  300.  from the largest elements of the language to the smallest.
  301.  
  302.  Chapters 3 through 11 describe the elements of the language including
  303.  notation and identifier conventions, conventions for data transfer (file
  304.  I/O), available data structures, and the data types through which these
  305.  data structures are accessed.
  306.  
  307.  Chapters 12 and 13 define the expressions and statements that are
  308.  supported by Microsoft Pascal.
  309.  
  310.  Chapters 14 through 18 describe the procedures, functions, and metalanguage
  311.  supported by Microsoft Pascal.
  312.  
  313.  Appendices A through G contain supplementary material including a
  314.  discussion of Microsoft Pascal features, and summaries of Microsoft Pascal
  315.  procedures, functions, metalanguage, and syntax.
  316.  
  317.  
  318.  
  319.  Chapter 1  Introduction to Microsoft Pascal
  320.  
  321.  ───────────────────────────────────────────────────────────────────────────
  322.  
  323.  1.1  Levels of Microsoft Pascal
  324.  
  325.  1.2  Selected Features
  326.  
  327.  1.3  Unimplemented Features
  328.  
  329.  
  330.  
  331.  Microsoft(R) Pascal offers systems programmers a clean, structured language
  332.  that is especially adept at quickly handling complex financial and
  333.  scientific algorithms. By generating native code, Microsoft Pascal offers
  334.  the advantages of a high level programming language without sacrificing
  335.  speed. Low level escapes to the machine level allow Microsoft Pascal
  336.  programs to achieve speeds comparable to assembly language.
  337.  
  338.  Microsoft Pascal offers fast numeric processing in the 8087 processing
  339.  environment and also provides 8087 emulation in the system software
  340.  package.
  341.  
  342.  
  343.  1.1  Levels of Microsoft Pascal
  344.  
  345.  
  346.  MS(TM)-Pascal is organized into three levels: standard, extend, and
  347.  system. The features of each level are discussed in more detail in Appendix
  348.  B, "Microsoft Pascal Features and the ISO Standard." Briefly, the
  349.  differences among the three levels are as follows:
  350.  
  351.      1.  Standard level
  352.  
  353.          At the standard level, programs must conform to the ISO standard.
  354.          Programs you create at this level are portable to and from machines
  355.          running other ISO-compatible Pascal compilers. There are some
  356.          minor MS-Pascal extensions to the standard that won't be caught as
  357.          errors at this level. For details of these extensions, as well as
  358.          other issues regarding the ISO standard, see Appendix B, "Microsoft
  359.          Pascal Features and the ISO Standard." In this manual, the phrases
  360.          "standard Pascal," "the ISO standard," and "at the standard level
  361.          of MS-Pascal" are generally synonymous.
  362.  
  363.      2.  Extend level
  364.  
  365.          The extend level is intended for structured and relatively safe
  366.          extensions to the ISO standard. Programs you create at this level
  367.          are portable among all machines that run MS-Pascal.
  368.  
  369.      3.  System level
  370.  
  371.          The system level includes all features available at the extend
  372.          level. It also includes some unstructured, machine-oriented
  373.          extensions, such as address types and the ability to access all
  374.          file control block fields, which are useful for systems
  375.          programming.
  376.  
  377.  In this manual, extensions to standard Pascal are called "features." A
  378.  complete list of these features and the level at which they are available
  379.  is given in Appendix B, "Microsoft Pascal Features and the ISO Standard."
  380.  Selected features are described briefly in the following list.
  381.  
  382.  In addition to these three levels, MS-Pascal has a large number of
  383.  "metacommands," that is, directives with which you can control the
  384.  compiler. See Chapter 18, "Microsoft Pascal Metacommands," for more
  385.  information.
  386.  
  387.  
  388.  1.2  Selected Features
  389.  
  390.  
  391.  The following list includes several of the features available at the extend
  392.  and system levels of MS-Pascal. For a complete list, see Section B.2,
  393.  "Summary of Microsoft Pascal Features."
  394.  
  395.      1.  Underscore in identifiers, which improves readability.
  396.  
  397.      2.  Nondecimal numbering (hexadecimal, octal, and binary), which
  398.          facilitates programming at the byte and bit level.
  399.  
  400.      3.  Structured constants, which you may declare in the declaration
  401.          section of a program or use in statements.
  402.  
  403.      4.  Variable length strings (type LSTRING), as well as special
  404.          predeclared procedures and functions for LSTRINGs, which enhance
  405.          standard Pascal's string handling capabilities.
  406.  
  407.      5.  Super arrays, which are special variable length arrays whose
  408.          declaration permits passing arrays of different lengths to a
  409.          reference parameter, as well as dynamic allocation of arrays of
  410.          different lengths.
  411.  
  412.      6.  Predeclared unsigned BYTE (0-255) and WORD (0-65535) types, which
  413.          facilitate programming at the system level.
  414.  
  415.      7.  Address types (segmented and unsegmented), which allow manipulation
  416.          of actual machine addresses at the system level.
  417.  
  418.      8.  String reads, which allow the standard procedures READ and READLN
  419.          to read strings as structures rather than character by character.
  420.  
  421.      9.  Interface to assembly language, provided by PUBLIC and EXTERN
  422.          procedures, functions, and variables, which allows low-level
  423.          interfacing to assembly language and library routines.
  424.  
  425.     10.  VALUE section, where you may declare the initial constant values of
  426.          variables in a program.
  427.  
  428.     11.  Function return values of a structured type as well as of a simple
  429.          type.
  430.  
  431.     12.  Direct (random access) files, accessible with the SEEK procedure,
  432.          which enhance standard Pascal's file accessing capabilities.
  433.  
  434.     13.  Lazy evaluation, a special internal mechanism for interactive files
  435.          which allows normal interactive input from terminals.
  436.  
  437.     14.  Structured BREAK and CYCLE statements, which allow structured exits
  438.          from a FOR, REPEAT, or WHILE loop; and the RETURN statement, which
  439.          allows a structured exit from a procedure or function.
  440.  
  441.     15.  OTHERWISE in CASE statements, whereby you avoid explicitly
  442.          specifying each CASE constant. OTHERWISE is also permitted with
  443.          variant records.
  444.  
  445.     16.  STATIC attribute for variables, which allows you to indicate that a
  446.          variable is to be allocated at a fixed location in memory rather
  447.          than on the stack.
  448.  
  449.     17.  ORIGIN attribute, which may be given to variables, procedures, and
  450.          functions to indicate their absolute location in memory.
  451.  
  452.     18.  INTERRUPT attribute for procedures, which signals the compiler to
  453.          give the procedure a special calling sequence that saves the
  454.          machine status on the stack upon entry and restores the machine
  455.          status upon exit.
  456.  
  457.     19.  Separate compilation of portions of a program (units and modules).
  458.  
  459.     20.  Conditional compilation, which uses conditional metacommands in
  460.          your MS-Pascal source file to switch on or off compilation of parts
  461.          of the source.
  462.  
  463.  
  464.  1.3  Unimplemented Features
  465.  
  466.  
  467.  The following features either are not presently implemented or are
  468.  implemented only as described in the following list:
  469.  
  470.      1.  OTHERWISE is not accepted in RECORD declarations.
  471.  
  472.      2.  Code is generated for PURE functions, but no checking is done.
  473.  
  474.      3.  The extend level operators SHL, SHR, and ISR are not available.
  475.  
  476.      4.  ENABIN, DISBIN, and VECTIN library routines are not available. The
  477.          INTERRUPT attribute is ignored.
  478.  
  479.      5.  No checking is done for invalid GOTOs and uninitialized REAL
  480.          values.
  481.  
  482.      6.  READ, READLN, and DECODE cannot have M and N parameters.
  483.  
  484.      7.  Enumerated I/O, for reading and writing enumerated constants as
  485.          strings, is not available.
  486.  
  487.      8.  The metacommands $tagck, $standard, $extend, and $system can be
  488.          given, but have no effect.
  489.  
  490.      9.  The $inconst metacommand does not accept string constants.
  491.  
  492.  
  493.  
  494.  Chapter 2  Language Overview
  495.  
  496.  ───────────────────────────────────────────────────────────────────────────
  497.  
  498.  2.1  Metacommands
  499.  
  500.  2.2  Programs and Compilable Parts of Programs
  501.  
  502.  2.3  Procedures and Functions
  503.  
  504.  2.4  Statements
  505.  
  506.  2.5  Expressions
  507.  
  508.  2.6  Variables
  509.  
  510.  2.7  Constants
  511.  
  512.        2.7.1  Types
  513.  
  514.  2.8  Identifiers
  515.  
  516.  2.9  Notation
  517.  
  518.  
  519.  
  520.  In this chapter you will find a summary description of Microsoft Pascal
  521.  from the largest elements of the language to the smallest. Each of the
  522.  remaining chapters of the manual discusses these elements in detail, from
  523.  the smallest element (notation) to the largest (metacommands).
  524.  
  525.  
  526.  2.1  Metacommands
  527.  
  528.  
  529.  The MS-Pascal metacommands provide a control language for the MS-Pascal
  530.  Compiler. The metacommands let you specify options that affect the overall
  531.  operation of a compilation. For example, you can conditionally compile
  532.  different source files, generate a listing file, or enable or disable
  533.  runtime error checking code.
  534.  
  535.  Metacommands are inserted inside comment statements. All of the
  536.  metacommands begin with a dollar sign ($). Some may also be given as
  537.  switches when you invoke the compiler.
  538.  
  539.  Although most implementations of Pascal have some type of compiler
  540.  control, the MS-Pascal metacommands are not part of standard Pascal and
  541.  hence are not portable.
  542.  
  543.  These are the metacommands currently available:
  544.  
  545.       $brave                    $page
  546.       $debug                    $pageif
  547.       $decmath                  $pagesize
  548.       $entry                    $pop
  549.       $errors                   $push
  550.       $extend                   $rangeck
  551.       $floatcalls               $real
  552.       $goto                     $rom
  553.       $include                  $runtime
  554.       $inconst                  $simple
  555.       $indexck                  $size
  556.       $initck                   $skip
  557.       $if $then $else $end      $speed
  558.       $integer                  $stackck
  559.       $line                     $standard
  560.       $linesize                 $subtitle
  561.       $list                     $symtab
  562.       $mathck                   $system
  563.       $message                  $tagck
  564.       $nilck                    $title
  565.       $ocode                    $warn
  566.       $optbug
  567.  
  568.  See Chapter 18, "Microsoft Pascal Metacommands," for a complete
  569.  discussion of metacommands.
  570.  
  571.  
  572.  2.2  Programs and Compilable Parts of Programs
  573.  
  574.  
  575.  The MS-Pascal Compiler processes programs, modules, and implementations
  576.  of units. Collectively, these compilable programs and parts of programs
  577.  are referred to as compilands. You can compile modules and implementations
  578.  of units separately and then later link them to a program without having to
  579.  recompile the module or unit.
  580.  
  581.  The fundamental unit of compilation is a program. A program has three
  582.  parts:
  583.  
  584.      1.  The program heading identifies the program and gives a list of
  585.          program parameters.
  586.  
  587.      2.  The declaration section follows the program heading and contains
  588.          declarations of labels, constants, types, variables, functions, and
  589.          procedures. Some of these declarations are optional.
  590.  
  591.      3.  The body follows all declarations. It is enclosed by the reserved
  592.          words BEGIN and END and is terminated by a period. The period is
  593.          the signal to the compiler that it has reached the end of the
  594.          source file.
  595.  
  596.  The following program illustrates this three-part structure:
  597.  
  598.       {Program heading}
  599.       PROGRAM FRIDAY (INPUT, OUTPUT);
  600.  
  601.       {Declaration section}
  602.       LABEL 1;
  603.       CONST DAYS_IN_WEEK = 7;
  604.       TYPE KEYBOARD_INPUT = CHAR;
  605.       VAR KEYIN : KEYBOARD_INPUT;
  606.  
  607.       {Program body}
  608.       BEGIN
  609.          WRITE('IS TODAY FRIDAY? ');
  610.       1: READLN(KEYIN);
  611.          CASE KEYIN OF
  612.           'Y', 'y' : WRITELN('It''s Friday.');
  613.           'N', 'n' : WRITELN('It''s not Friday.');
  614.          OTHERWISE
  615.             WRITELN('Enter Y or N.');
  616.             WRITE('Please re-enter: ');
  617.             GOTO 1
  618.          END
  619.       END.
  620.  
  621.  This three-part structure (heading, declaration section, and body) is used
  622.  throughout the Pascal language. Procedures, functions, modules, and units
  623.  are all similar in structure to a program.
  624.  
  625.  Modules are program-like units of compilation that contain the declaration
  626.  of variables, constants, types, procedures, and functions, but no program
  627.  statements. You can compile a module separately and later link it to a
  628.  program, but it cannot be executed by itself.
  629.  
  630.  Example of a module:
  631.  
  632.       {Module heading}
  633.       MODULE MODPART;
  634.  
  635.       {Declaration section}
  636.       CONST PI = 3.14;
  637.  
  638.       PROCEDURE PARTA;
  639.          BEGIN
  640.            WRITELN ('parta')
  641.          END;
  642.  
  643.       {Body}
  644.       END.
  645.  
  646.  A module, like a program, ends with a period. Unlike a program, a
  647.  module contains no program statements.
  648.  
  649.  A unit has two sections: an interface and an implementation. Like a
  650.  module, an implementation may be compiled separately and later linked to
  651.  the rest of the program. The interface contains the information that lets
  652.  you connect a unit to other units, modules, and programs.
  653.  
  654.  Example of a unit:
  655.  
  656.       {Heading for interface}
  657.       INTERFACE;
  658.       UNIT MUSIC (SING, TOP);
  659.  
  660.       {Declarations for interface}
  661.       VAR TOP : INTEGER;
  662.       PROCEDURE SING;
  663.  
  664.       {Body of interface}
  665.       BEGIN
  666.       END;
  667.  
  668.       {Heading for implementation}
  669.       IMPLEMENTATION OF MUSIC;
  670.  
  671.       {Declaration for implementation}
  672.       PROCEDURE SING;
  673.       BEGIN
  674.          FOR I := 1 TO TOP DO
  675.          BEGIN
  676.            WRITE ('FA '); WRITELN ('LA LA')
  677.          END
  678.       END;
  679.  
  680.       {Body of implementation}
  681.       BEGIN
  682.          TOP := 5
  683.       END.
  684.  
  685.  A unit, like a program or a module, ends with a period.
  686.  
  687.  Modules and units let you develop large structured programs that can be
  688.  broken into parts. This practice is advantageous in the following
  689.  situations:
  690.  
  691.      1.  If a program is large, breaking it into parts makes it easier to
  692.          develop, test, and maintain.
  693.  
  694.      2.  If a program is large and recompiling the entire source file is
  695.          time consuming, breaking the program into parts saves compilation
  696.          time.
  697.  
  698.      3.  If you intend to include certain routines in a number of different
  699.          programs, you can create a single object file that contains these
  700.          routines and then link it to each of the programs in which the
  701.          routines are used.
  702.  
  703.      4.  If certain routines have different implementations, you might place
  704.          them in a module to test the validity of an algorithm and later
  705.          create and implement similar routines in assembly language to
  706.          increase the speed of the algorithm.
  707.  
  708.  See Chapter 17, "Compilable Parts of a Program," for a complete
  709.  discussion of programs, modules, and units.
  710.  
  711.  
  712.  2.3  Procedures and Functions
  713.  
  714.  
  715.  Procedures and functions act as subprograms that execute under the
  716.  supervision of a main program. However, unlike programs, procedures and
  717.  functions can be nested within each other and can even call themselves.
  718.  Furthermore, they have sophisticated parameter-passing capabilities that
  719.  programs lack.
  720.  
  721.  Procedures are invoked as statements; functions can be invoked in
  722.  expressions wherever values are called for.
  723.  
  724.  A procedure declaration, like a program, has a heading, a declaration
  725.  section, and a body.
  726.  
  727.  Example of a procedure declaration:
  728.  
  729.       {Heading}
  730.       PROCEDURE COUNT_TO (NUM : INTEGER);
  731.  
  732.       {Declaration section}
  733.       VAR I : INTEGER;
  734.  
  735.       {Body}
  736.       BEGIN
  737.         FOR I := 1 TO NUM DO WRITELN (I)
  738.       END;
  739.  
  740.  A function is a procedure that returns a value of a particular type;
  741.  hence, a function declaration must indicate the type of the return value.
  742.  
  743.  Example of a function declaration:
  744.  
  745.       {Heading}
  746.       FUNCTION ADD (VAL1, VAL2 : INTEGER) : INTEGER;
  747.  
  748.       {Declaration section empty}
  749.  
  750.       {Body}
  751.       BEGIN
  752.          ADD := VAL1 + VAL2
  753.       END;
  754.  
  755.  Procedures and functions look somewhat different from programs, in that
  756.  their parameters have types and other options. Like the body of a program,
  757.  the body of a procedure or a function is enclosed by the reserved words
  758.  BEGIN and END; however, a semicolon rather than a period follows the word
  759.  "END".
  760.  
  761.  Declaring a procedure or function is entirely distinct from using it in
  762.  a program.
  763.  
  764.  For example, the procedure and function declared above might actually
  765.  appear in a program as follows:
  766.  
  767.       TARGET_NUMBER := ADD (5, 6);
  768.       COUNT_TO (TARGET_NUMBER);
  769.  
  770.  See Chapter 14, "Introduction to Procedures and Functions," for a
  771.  complete discussion of procedures and functions.
  772.  
  773.  See Chapter 15, "Available Procedures and Functions," and Chapter 16,
  774.  "File-Oriented Procedures and Functions," for a discussion of procedures
  775.  and functions that are predeclared as part of the MS-Pascal language.
  776.  
  777.  
  778.  2.4  Statements
  779.  
  780.  
  781.  Statements perform actions, such as computing, assigning, altering the
  782.  flow of control, and reading and writing files. Statements are found in the
  783.  bodies of programs, procedures, and functions and are executed as a program
  784.  runs. MS-Pascal statements perform the actions shown in Table 2.1.
  785.  
  786.  
  787.  Table 2.1
  788.  Summary of Microsoft Pascal Statements
  789. ╓┌────────────┌──────────────────────────────────────────────────────────────╖
  790.  Statement    Purpose
  791.  ───────────────────────────────────────────────────────────────────────────
  792.  Assignment   Replaces the current value of a variable with a new
  793.               value
  794.  
  795.  BREAK        Exits the currently executing loop
  796.  
  797.  CASE         Allows for the selection of one action from a choice
  798.               of many, based on the value of an expression
  799.  
  800.  Statement    Purpose
  801. 
  802.  CYCLE        Starts the next iteration of a loop
  803.  
  804.  FOR          Executes a statement repeatedly while a progression
  805.               of values is assigned to a control variable
  806.  
  807.  GOTO         Continues processing at another part of the
  808.               program
  809.  
  810.  IF           Together with THEN and ELSE, allows for
  811.               conditional execution of a statement
  812.  
  813.  Procedure    Invokes a procedure with actual parameter
  814.  call         values
  815.  
  816.  REPEAT       Repeats a sequence of statements one or more times,
  817.               until a Boolean expression becomes true
  818.  
  819.  RETURN       Exits the current procedure, function, program, or
  820.               implementation
  821.  Statement    Purpose
  822.              implementation
  823.  
  824.  WHILE        Repeats a statement zero or more times, until a
  825.               Boolean expression becomes false
  826.  
  827.  WITH         Opens the scope of a statement to include the fields
  828.               of one or more records, so that you can refer to the
  829.               fields directly
  830.  
  831.  See Chapter 13, "Statements," for a detailed discussion of each of
  832.  these statements.
  833.  
  834.  
  835.  2.5  Expressions
  836.  
  837.  
  838.  An expression is a formula for computing a value. It consists of a
  839.  sequence of operators (which indicate the action to be performed) and
  840.  operands (which are the value on which the operation is performed).
  841.  Operands may contain function invocations, variables, constants, or even
  842.  other expressions. In the following expression, plus (+) is an operator,
  843.  while A and B are operands:
  844.  
  845.       A + B
  846.  
  847.  There are three basic kinds of expressions:
  848.  
  849.      1.  Arithmetic expressions perform arithmetic operations on the
  850.          operands in the expression.
  851.  
  852.      2.  Boolean expressions perform logical and comparison operations with
  853.          Boolean results.
  854.  
  855.      3.  Set expressions perform combining and comparison operations on
  856.          sets, with Boolean or set results.
  857.  
  858.  Expressions always return values of a specific type. For instance, if
  859.  A, B, C, and D are all REAL variables, then the following expression
  860.  evaluates to a REAL result:
  861.  
  862.       A * B + (C / D) + 12.3
  863.  
  864.  Expressions may also include function designators:
  865.  
  866.       ADDREAL (2, 3) + (C / D)
  867.  
  868.  ADDREAL is a function that has been previously declared in a program. It
  869.  has two REAL value parameters, which it adds together to obtain a total.
  870.  This total is the return value of the function, which is then added to
  871.  (C / D).
  872.  
  873.  Expressions are not statements, but may be components of statements. In
  874.  the following example, the entire line is a statement; only the portion
  875.  after the equal sign is an expression:
  876.  
  877.       X := 2 / 3 + A * B
  878.  
  879.  See Chapter 12, "Expressions," for a detailed discussion of expressions.
  880.  
  881.  
  882.  2.6  Variables
  883.  
  884.  
  885.  A variable is a value that is expected to change during the course of a
  886.  program. Every variable must be of a specific data type.
  887.  
  888.  After you declare a variable in the heading or declaration section of a
  889.  compiland, procedure, or function, it may be used in any of the following
  890.  ways:
  891.  
  892.      1.  You may initialize it, in the VALUE section of a program.
  893.  
  894.      2.  You may assign it a value, with an assignment statement.
  895.  
  896.      3.  You may pass it as a parameter to a procedure or function.
  897.  
  898.      4.  You may use it in an expression.
  899.  
  900.  The VALUE section is an MS-Pascal feature that applies only to
  901.  statically allocated variables (variables with a fixed address in memory).
  902.  First you declare the variables, as shown in the following example:
  903.  
  904.       VAR  I, J, K, L : INTEGER;
  905.  
  906.  Then you assign them initial values in the VALUE section:
  907.  
  908.       VALUE  I := 1; J := 2; K := 3; L := 4;
  909.  
  910.  Later, in statements, the variables can be assigned to, and used as
  911.  operands in expressions:
  912.  
  913.       I := J + K + L;
  914.       J := 1 + 2 + 3;
  915.       K := (J * K) + 9 + (L DIV J);
  916.  
  917.  See Chapter 11, "Variables and Values," for a complete discussion of
  918.  variables.
  919.  
  920.  
  921.  2.7  Constants
  922.  
  923.  
  924.  A constant is a value that is not expected to change during the course
  925.  of a program. At the standard level, a constant may be:
  926.  
  927.      1.  a number, such as 1.234 and 100
  928.  
  929.      2.  a string enclosed in single quotation marks, such as 'Miracle' or
  930.          'A1207'
  931.  
  932.      3.  a constant identifier that is a synonym for a numeric or string
  933.          constant
  934.  
  935.  You declare constant identifiers in the CONST section of a compiland,
  936.  procedure, or function.
  937.  
  938.       CONST  REAL_CONST = 1.234;
  939.              MAX_VAL = 100;
  940.              TITLE = 'Pascal';
  941.  
  942.  Because the order of declarations is flexible in MS-Pascal, you can declare
  943.  constants anywhere in the declaration section of a compilable part of a
  944.  program, any number of times.
  945.  
  946.  Constants are closely tied to the concepts of variables and types.
  947.  Variables are all of some type; types, in turn, designate a range of
  948.  assumable values. These values, ultimately, are all constants.
  949.  
  950.  Two powerful extensions in MS-Pascal are structured constants and
  951.  constant expressions.
  952.  
  953.      1.  VECTOR, in the following example, is an array constant:
  954.  
  955.              CONST VECTOR = VECTORTYPE (1, 2, 3, 4, 5);
  956.  
  957.      2.  MAXVAL, in the following example, is a constant expression (A, B,
  958.          C, and D must also be constants):
  959.  
  960.              CONST MAXVAL = A * (B DIV C) + D - 5;
  961.  
  962.  See Chapter 10, "Constants," for a complete discussion of these and
  963.  other aspects of constants.
  964.  
  965.  
  966.  2.7.1  Types
  967.  
  968.  
  969.  Much of MS-Pascal's power and flexibility lies in its data typing
  970.  capability. Although a great variety of data types are available, they may
  971.  be divided into three broad categories: simple, structured, and reference
  972.  types.
  973.  
  974.      1.  A simple data type represents a single value. The simple types
  975.          include the following:
  976.  
  977.          INTEGER     enumerated
  978.          WORD        subrange
  979.          CHAR        REAL
  980.          BOOLEAN     INTEGER4
  981.  
  982.      2.  A structured data type represents a collection of values. The
  983.          structured types include the following:
  984.  
  985.          ARRAY
  986.          RECORD
  987.          SET
  988.          FILE
  989.  
  990.      3.  Reference types allow recursive definition of types.
  991.  
  992.  All variables in MS-Pascal must be assigned a data type. A type is
  993.  either predeclared (e.g., INTEGER and REAL) or defined in the declaration
  994.  section of a program. The following sample type declaration creates a type
  995.  that can store information about a student:
  996.  
  997.       TYPE
  998.          STUDENT = RECORD
  999.             AGE : 5..18;
  1000.             SEX : (MALE, FEMALE);
  1001.             GRADE : INTEGER;
  1002.             GRADE_PT : REAL;
  1003.             SCHEDULE : ARRAY [1..10] OF CLASSES
  1004.          END;
  1005.  
  1006.  For a detailed discussion of data types, see the following chapters:
  1007.  
  1008.       Chapter 5, "Introduction to Data Types"
  1009.       Chapter 6, "Simple Types"
  1010.       Chapter 7, "Arrays, Records, and Sets"
  1011.       Chapter 8, "Files"
  1012.       Chapter 9, "Reference and Other Types"
  1013.  
  1014.  
  1015.  2.8  Identifiers
  1016.  Identifiers are names that denote the constants, variables, data types,
  1017.  procedures, functions, and other elements of a Pascal program. Procedures
  1018.  and functions must have identifiers; constants, type, and variables may
  1019.  have identifiers (and it is useful if they do).
  1020.  
  1021.  You, the programmer, make up most of the identifiers in a program and
  1022.  assign them meaning in declarations. Other identifiers are the names of
  1023.  variables, data types, procedures, and functions that are built into the
  1024.  language and need not be declared.
  1025.  
  1026.  An identifier must begin with a letter (A through Z and a through z).
  1027.  The initial letter may be followed by any number of letters, digits (0
  1028.  through 9), or underscore characters.
  1029.  
  1030.  The underscore in MS-Pascal is significant. Thus, the following are not
  1031.  identical:
  1032.  
  1033.       FOREST
  1034.       FOR_EST
  1035.  
  1036.  The only restriction on identifiers is that you must not choose a Pascal
  1037.  reserved word (see Section 3.3.2, "Reserved Words," for a discussion of
  1038.  reserved words; see Appendix E," Summary of Microsoft Pascal Reserved
  1039.  Words," for a complete list).
  1040.  
  1041.  Furthermore, most compilers have some restriction either on the
  1042.  absolute length of an identifier or on the number of characters that are
  1043.  considered significant. See Appendix B, "Version Specifics," in your
  1044.  Microsoft Pascal Compiler User's Guide for any limitations imposed by your
  1045.  version of the compiler.
  1046.  
  1047.  See Chapter 4, "Identifiers," for a complete discussion of identifiers
  1048.  in MS-Pascal.
  1049.  
  1050.  
  1051.  2.9  Notation
  1052.  
  1053.  
  1054.  The basis of all Pascal programs is an irreducible set of symbols with
  1055.  which the higher syntactic components of the language are created.
  1056.  
  1057.  The underlying notation is the ASCII character set, divided into the
  1058.  following syntactic groups:
  1059.  
  1060.      1.  Identifiers are the names given to individual instances of
  1061.          components of the language.
  1062.  
  1063.      2.  Separators are characters that delimit adjacent numbers, reserved
  1064.          words, and identifiers.
  1065.  
  1066.      3.  Special symbols include punctuation, operators, and reserved words.
  1067.  
  1068.      4.  Some characters are unused by MS-Pascal but are available for use
  1069.          in a comment or string literal.
  1070.  
  1071.  A good understanding of this notation will increase your productivity by
  1072.  reducing the number of subtle syntactic errors in a program. See
  1073.  Chapter 3, "Notation," for a detailed discussion of MS-Pascal notation.
  1074.  
  1075.  
  1076.  
  1077.  Chapter 3  Notation
  1078.  
  1079.  ───────────────────────────────────────────────────────────────────────────
  1080.  
  1081.  3.1  Components of Identifiers
  1082.  
  1083.        3.1.1  Letters
  1084.  
  1085.        3.1.2  Digits
  1086.  
  1087.        3.1.3  The Underscore Character
  1088.  
  1089.  3.2  Separators
  1090.  
  1091.  3.3  Special Symbols
  1092.  
  1093.        3.3.0 Punctuation
  1094.  
  1095.        3.3.1  Operators
  1096.  
  1097.        3.3.2  Reserved Words
  1098.  
  1099.  3.4  Unused Characters
  1100.  
  1101.  3.5  Notes on Characters
  1102.  
  1103.  
  1104.  
  1105.  All components of the Microsoft Pascal language are constructed from the
  1106.  standard ASCII character set. Characters make up lines, each of which is
  1107.  separated by a character specific to your operating system. Lines make up
  1108.  files.
  1109.  
  1110.  Within a line, individual characters or groups of characters fall into
  1111.  one (or more) of four broad categories:
  1112.  
  1113.      1.  components of identifiers
  1114.  
  1115.      2.  separators
  1116.  
  1117.      3.  special symbols
  1118.  
  1119.      4.  unused characters
  1120.  
  1121.  
  1122.  3.1  Components of Identifiers
  1123.  
  1124.  
  1125.  Identifiers are names that denote the constants, variables, data types,
  1126.  procedures, functions, and other elements of a Pascal program.
  1127.  
  1128.  The use of identifiers is described thoroughly in Chapter 4,
  1129.  "Identifiers." This section discusses only how to construct them.
  1130.  
  1131.  Identifiers must begin with a letter; subsequent components may include
  1132.  letters, digits, and underscore characters.
  1133.  
  1134.  Although, in theory, there is no limit on the number of characters in
  1135.  an identifier, most implementations restrict the length in some way. See
  1136.  Appendix B, "Version Specifics," in your Microsoft Pascal Compiler User's
  1137.  Guide for any limitations that may apply to your machine.
  1138.  
  1139.  
  1140.  3.1.1  Letters
  1141.  
  1142.  
  1143.  In identifiers, only the uppercase letters A through Z are significant.
  1144.  You may use lowercase letters for identifiers in a source program.
  1145.  However, the MS-Pascal Compiler converts all lowercase letters in
  1146.  identifiers to the corresponding uppercase letters.
  1147.  
  1148.  Letters in comments or in string literals may be either uppercase or
  1149.  lowercase; the difference is significant. No mapping of lowercase to
  1150.  uppercase occurs in either comments or string literals.
  1151.  
  1152.  
  1153.  3.1.2  Digits
  1154.  
  1155.  
  1156.  Digits in Pascal are the numbers zero through nine. Digits can occur in
  1157.  identifiers (for example, AS129M) or in in numeric constants (for
  1158.  example, 1.23 and 456).
  1159.  
  1160.  
  1161.  3.1.3  The Underscore Character
  1162.  
  1163.  
  1164.  The underscore (_) is the only nonalphanumeric character allowed in
  1165.  identifiers. The underscore is significant in MS-Pascal. Use it like a
  1166.  space to improve readability.
  1167.  
  1168.  The identifiers in the left-hand column below demonstrate how the
  1169.  underscore improves readability. Note, however, that they will not be
  1170.  equal to those in the right-hand column.
  1171.  
  1172.       POWER_OF_TEN          POWEROFTEN
  1173.       MY_DOG_MAUDE          MYDOGMAUDE
  1174.  
  1175.  
  1176.  3.2  Separators
  1177.  
  1178.  
  1179.  Separators delimit adjacent numbers, reserved words, and identifiers,
  1180.  none of which should have separators embedded within them.
  1181.  
  1182.  A separator can be any of the following:
  1183.  
  1184.      1.  the space character
  1185.  
  1186.      2.  the tab character
  1187.  
  1188.      3.  the form feed character
  1189.  
  1190.      4.  the new line marker
  1191.  
  1192.      5.  the comment
  1193.  
  1194.  Comments in standard Pascal take one of these forms:
  1195.  
  1196.       {This is a comment, enclosed in braces.}
  1197.       (*This is an alternate form of comment.*)
  1198.  
  1199.  The second form is generally used if braces are unavailable on a particular
  1200.  machine. Comments in either of these forms may span more than one line.
  1201.  
  1202.  At the extend level, MS-Pascal also allows comments that begin with an
  1203.  exclamation point:
  1204.  
  1205.       ! The rest of this line is a comment.
  1206.  
  1207.  For comments in this form, the new line character delimits the comment.
  1208.  
  1209.  Nested comments are permitted in MS-Pascal, so long as each level has
  1210.  different delimiters. Thus, when a comment is started, the compiler
  1211.  ignores succeeding text until it finds the matching end-of-comment.
  1212.  However, such nesting may not be portable.
  1213.  
  1214.  Always use separators between identifiers and numbers. If you fail to
  1215.  do so, the compiler will generally issue an error or warning message. In a
  1216.  few cases, the MS-Pascal Compiler accepts a missing separator without
  1217.  generating an error message.
  1218.  
  1219.  For example, at extend level,
  1220.  
  1221.       100MOD#127
  1222.  
  1223.  is accepted as 100 MOD #127, where #127 is a hexadecimal number. However,
  1224.  
  1225.       100MOD127
  1226.  
  1227.  is assumed to be 100 followed by the identifier MOD127.
  1228.  
  1229.  
  1230.  3.3  Special Symbols
  1231.  
  1232.  
  1233.  Special symbols fall into three categories:
  1234.  
  1235.      1.  punctuation
  1236.  
  1237.      2.  operators
  1238.  
  1239.      3.  reserved words
  1240.  
  1241.  
  1242.  3.3.0 Punctuation
  1243.  
  1244.  Punctuation in MS-Pascal serves a variety of purposes, including those
  1245.  shown in Table 3.1.
  1246.  
  1247.  
  1248.  Table 3.1.
  1249.  Summary of Punctuation in Microsoft Pascal
  1250. ╓┌──────┌────────────────────────────────────────────────────────────────────╖
  1251.  Symbol Purpose
  1252.  ───────────────────────────────────────────────────────────────────────────
  1253.  {  }   Braces delimit comments.
  1254.  
  1255.  [  ]   Brackets delimit array indices, sets, and attributes.
  1256.         They may also replace the reserved words BEGIN and END in
  1257.         a program.
  1258.  
  1259.  (  )   Parentheses delimit expressions, parameter lists, and
  1260.         program parameters.
  1261.  
  1262.  Symbol Purpose
  1263. 
  1264.  '      Single quotation marks enclose string literals.
  1265.  
  1266.  :=     The colon-equal symbol assigns values to variables in
  1267.         assignment statements and in VALUE sections.
  1268.  
  1269.  ;      The semicolon separates statements and declarations.
  1270.  
  1271.  :      The colon separates variables from types and labels from
  1272.         statements.
  1273.  
  1274.  =      The equal sign separates identifiers and type clauses in a
  1275.         TYPE section.
  1276.  
  1277.  ,      The comma separates the components of lists.
  1278.  
  1279.  ..     The double period denotes a subrange.
  1280.  
  1281.  .      The period designates the end of a program, indicates the
  1282.         fractional part of a real number, and also delimits fields
  1283.  Symbol Purpose
  1284.        fractional part of a real number, and also delimits fields
  1285.         in a record.
  1286.  
  1287.  ^      The up arrow denotes the value pointed to by a reference
  1288.         value.
  1289.  
  1290.  #      The number sign denotes nondecimal numbers.
  1291.  
  1292.  $      The dollar sign prefixes metacommands.
  1293.  
  1294.  
  1295.  3.3.1  Operators
  1296.  
  1297.  
  1298.  Operators are a form of punctuation that indicate some operation to be
  1299.  performed. Some are alphabetic, others are one or two nonalphanumeric
  1300.  characters. Any operators that consist of more than one character must not
  1301.  have a separator between characters.
  1302.  
  1303.  The operators that consist only of nonalphabetic characters are the
  1304.  following:
  1305.  
  1306.      +   -   *   /   >   <  =   <>  <=  >=
  1307.  
  1308.  Some operators (e.g., NOT and DIV) are reserved words instead of
  1309.  nonalphabetic characters.
  1310.  
  1311.  See Chapter 12, "Expressions," for a complete list of the nonalphabetic
  1312.  operators and a discussion of the use of operators in expressions.
  1313.  
  1314.  
  1315.  3.3.2  Reserved Words
  1316.  
  1317.  
  1318.  Reserved words are a fixed part of the MS-Pascal language. They include,
  1319.  for example, statement names (e.g., BREAK) and words like BEGIN and END
  1320.  that bracket the main body of a program. See Appendix E, "Summary of
  1321.  Microsoft Pascal Reserved Words," for a complete list.
  1322.  
  1323.  You cannot create an identifier that is the same as any reserved word.
  1324.  You may, however, declare an identifier that contains within it the letters
  1325.  of a reserved word (for example, the identifier DOT containing the reserved
  1326.  word DO).
  1327.  
  1328.  There are several categories of reserved words in MS-Pascal:
  1329.  
  1330.      1.  reserved words for standard level MS-Pascal
  1331.  
  1332.      2.  reserved words added for extend level MS-Pascal features
  1333.  
  1334.      3.  reserved words added for system level MS-Pascal features
  1335.  
  1336.      4.  names of attributes
  1337.  
  1338.      5.  names of directives
  1339.  
  1340.  See Appendix E, "Summary of Microsoft Pascal Reserved Words," for a
  1341.  complete list of reserved words. Look in the index for the pages where
  1342.  each is discussed in this manual.
  1343.  
  1344.  
  1345.  3.4  Unused Characters
  1346.  
  1347.  
  1348.  A few printing characters are not used in MS-Pascal:
  1349.  
  1350.      %   &   "   |   ~
  1351.  
  1352.  You may, however, use them within comments or string literals.
  1353.  
  1354.  A number of other nonprinting ASCII characters will generate error
  1355.  messages if you use them in a source file other than in a comment or string
  1356.  literal:
  1357.  
  1358.      1.  the characters from CHR (0) to CHR (31), except the tab and form
  1359.          feed, CHR (9) and CHR (12), respectively
  1360.  
  1361.      2.  the characters from CHR (127) to CHR (255)
  1362.  
  1363.  The tab character, CHR (9), is treated like a space and is passed on
  1364.  to the listing file. A form feed, CHR (12), is treated like a space and
  1365.  starts a new page in the listing file.
  1366.  
  1367.  
  1368.  3.5  Notes on Characters
  1369.  
  1370.  
  1371.  This section discusses special notational properties of the MS-Pascal
  1372.  language not mentioned elsewhere in this chapter. Characters within a
  1373.  comment or string literal are always legal and have no special effects.
  1374.  
  1375.  MS-Pascal allows the following substitutions:
  1376.  
  1377.      If Your Keyboard Lacks    Use This Instead
  1378.      ───────────────────────────────────────────────────────────────────────
  1379.      [                         (.
  1380.      ]                         .)
  1381.      ^                         @ or ?
  1382.      @                         ^ or ?
  1383.  
  1384.  The substitution of a question mark (?) for an up arrow (_) is a
  1385.  minor extension to the ISO standard.
  1386.  
  1387.  Table 3.2 gives a list of pairs of printing characters that are the
  1388.  same ASCII character.
  1389.  
  1390.  
  1391.  Table 3.2
  1392.  Equivalent ASCII Characters
  1393. ╓┌───────────┌───────────┌───────────────────────────────────────────────────╖
  1394.  ASCII       Prints as   Equivalent Characters
  1395.  ───────────────────────────────────────────────────────────────────────────
  1396.  CHR (94)    ^           up arrow, caret
  1397.  CHR (95)    -           underscore, left arrow
  1398.  CHR (35)    #           number sign, English poound sign
  1399.  CHR (36)    $           dollar sign, scarab (circle with
  1400.                          four spikes)
  1401.  
  1402.  
  1403.  
  1404.  Chapter 4  Identifiers
  1405.  
  1406.  ───────────────────────────────────────────────────────────────────────────
  1407.  
  1408.  4.1  Creating an Identifier
  1409.  
  1410.  4.2  Declaring an Identifier
  1411.  
  1412.  4.3  The Scope of Identifiers
  1413.  
  1414.  4.4  Predeclared Identifiers
  1415.  
  1416.  
  1417.  
  1418.  Procedures and functions must have identifiers. Constants, types, and
  1419.  variables may have identifiers and it is useful if they do. Some
  1420.  identifiers are predeclared; others you declare in a declaration section.
  1421.  
  1422.  
  1423.  4.1  Creating an Identifier
  1424.  
  1425.  
  1426.  Standard Pascal allows identifiers for the following elements of the
  1427.  Pascal language:
  1428.  
  1429.       types
  1430.       constants
  1431.       variables
  1432.       procedures
  1433.       functions
  1434.       programs
  1435.       fields and tag fields in records
  1436.  
  1437.  The following Microsoft Pascal features at the extend level also allow
  1438.  identifiers:
  1439.  
  1440.       super array types
  1441.       modules
  1442.       units
  1443.       statement labels
  1444.  
  1445.  An identifier consists of a sequence of alphanumeric characters or
  1446.  underscore characters. The first character must be alphabetic. Underscores
  1447.  in identifiers are allowed, and significant, at all levels of MS-Pascal.
  1448.  Two underscores in a row or an underscore at the end of an identifier are
  1449.  permitted.
  1450.  
  1451.  Subject to the restrictions noted below, identifiers can be as long as
  1452.  you want. They must, however, fit on a single line. At least the first 19
  1453.  characters of an identifier are significant; in some versions of MS-Pascal,
  1454.  as many as 31 characters are significant.
  1455.  
  1456.  An identifier longer than the significance length generates a warning
  1457.  but not an error message; the excess characters are ignored by the
  1458.  compiler. See Appendix B, "Version Specifics," in your Microsoft Pascal
  1459.  Compiler User's Guide for the significance length in your implementation.
  1460.  
  1461.  Standard Pascal allows unsigned integers as statement labels.
  1462.  Statement labels have the same scope rules as identifiers (see Section
  1463.  4.3, "The Scope of Identifiers"). Leading zeros are not significant. Extend
  1464.  level MS-Pascal allows labels that are normal alphabetic identifiers.
  1465.  
  1466.  The identifiers used for a program, module, or unit, as well as
  1467.  identifiers with the PUBLIC or EXTERN attribute, are passed to the linker.
  1468.  The operating system of a machine on which you plan to link and run a
  1469.  compiled MS-Pascal program may impose further identifier length
  1470.  restrictions on identifiers used as linker global symbols. Furthermore,
  1471.  the object code listing and debugger symbol table may truncate variable and
  1472.  procedural identifiers to six characters.
  1473.  
  1474.  Writing programs for use with other compilers and operating systems
  1475.  imposes an additional constraint on a program. Such a program must conform
  1476.  to the identifier restrictions for the worst possible case.
  1477.  
  1478.  For portability in general, the following practices are recommended:
  1479.  
  1480.      1.  Make all identifiers unique in their first eight characters.
  1481.  
  1482.      2.  Make external identifiers unique in their first six characters.
  1483.  
  1484.      3.  Limit statement labels to four digits without leading zeros.
  1485.  
  1486.  Identifiers of seven characters or fewer save space during compilation.
  1487.  
  1488.  ───────────────────────────────────────────────────────────────────────────
  1489.  Note
  1490.    All identifiers used internally by the runtime system are four alphabetic
  1491.    characters followed by the characters QQ. Avoid this form when creating
  1492.    new names yourself.
  1493.  ───────────────────────────────────────────────────────────────────────────
  1494.  
  1495.  
  1496.  4.2  Declaring an Identifier
  1497.  
  1498.  
  1499.  You declare identifiers and associate them with language objects in the
  1500.  declaration section of a program, module, interface, implementation,
  1501.  procedure, or function. Examples of identifiers, the objects they
  1502.  represent, and the syntax used to declare them are shown in Table 4.1.
  1503.  Although the details vary, the basic form of the declaration of the
  1504.  identifier for each of these elements is similar.
  1505.  
  1506.  
  1507.  Table 4.1.
  1508.  Declaring Identifiers
  1509. ╓┌────────────────┌──────────────────┌───────────────────────────────────────╖
  1510.  Object           Identifier         Declaration
  1511.  ───────────────────────────────────────────────────────────────────────────
  1512.  Program          Z                  PROGRAM Z (INPUT, OUTPUT)
  1513.  Module           XXX                MODULE XXX
  1514.  Object           Identifier         Declaration
  1515. Module           XXX                MODULE XXX
  1516.  Interface        UUU                INTERFACE; UNIT UUU
  1517.  Implementation   UUU                IMPLEMENTATION of UUU
  1518.  Constant         DAYS               CONST DAYS = 365
  1519.  Type             LETTERS            TYPE LETTERS = 'A'..'Z'
  1520.  Record fields    X, Y, Z            TYPE A = RECORD
  1521.                                          X, Y ,Z : REAL END
  1522.  Variable         J                  VAR J : INTEGER
  1523.  Label            1                  LABEL 1
  1524.  Label            HAWAII             LABEL HAWAII
  1525.  Procedure        BANG               PROCEDURE BANG
  1526.  Function         FOO                FUNCTION FOO : INTEGER
  1527.  
  1528.  
  1529.  4.3  The Scope of Identifiers
  1530.  
  1531.  
  1532.  An identifier is defined for the duration of the procedure, function,
  1533.  program, module, implementation, or interface in which you declare it.
  1534.  This holds true for any nested procedures or functions. An identifier's
  1535.  association must be unique within its scope; that is, it must not name more
  1536.  than one thing at a time.
  1537.  
  1538.  A nested procedure or function can redefine an identifier only if the
  1539.  identifier has not already been used in it. However, the compiler does not
  1540.  identify such redefinition as an error, but will generally use the first
  1541.  definition until the second occurs. A special exception for reference types
  1542.  is discussed in Section 9.1.5, "Notes on Reference Types."
  1543.  
  1544.  
  1545.  4.4  Predeclared Identifiers
  1546.  
  1547.  
  1548.  A number of identifiers are already a part of the MS-Pascal language.
  1549.  This category includes the identifiers for predeclared types, super array
  1550.  types, constants, file variables, functions, and procedures. You can use
  1551.  them freely, without declaring them. However, they differ from reserved
  1552.  words in that you may redefine them whenever you wish.
  1553.  
  1554.  At the standard level, the following identifiers are predeclared:
  1555.  
  1556.       ABS          FLOAT        PACK         SIN
  1557.       ARCTAN       GET          PAGE         SQR
  1558.       BOOLEAN      INPUT        PRED         SQRT
  1559.       CHAR         INTEGER      PUT          SUCC
  1560.       CHR          LN           READ         TEXT
  1561.       COS          MAXINT       READLN       TRUE
  1562.       DISPOSE      NEW          REAL         TRUNC
  1563.       EOF          ODD          RESET        UNPACK
  1564.       EOLN         ORD          REWRITE      WRITE
  1565.       EXP          OUTPUT       ROUND        WRITELN
  1566.       FALSE
  1567.  
  1568.  Features at the extend and system levels add the following to the list of
  1569.  predeclared identifiers in MS-Pascal.
  1570.  
  1571.      1.  String intrinsics
  1572.  
  1573.          CONCAT      INSERT
  1574.          COPYLST     POSITN
  1575.          COPYSTR     SCANEQ
  1576.          DELETE      SCANNE
  1577.  
  1578.      2.  Extend level intrinsics
  1579.  
  1580.          ABORT       LOBYTE
  1581.          BYWORD      LOWER
  1582.          DECODE      RESULT
  1583.          ENCODE      SIZEOF
  1584.          EVAL        UPPER
  1585.          HIBYTE
  1586.  
  1587.      3.  System level intrinsics
  1588.  
  1589.          FILLC       MOVESL
  1590.          FILLSC      MOVESR
  1591.          MOVEL       RETYPE
  1592.          MOVER
  1593.  
  1594.      4.  Extend level I/O
  1595.  
  1596.          ASSIGN      READFN
  1597.          CLOSE       READSET
  1598.          DIRECT      SEEK
  1599.          DISCARD     SEQUENTIAL
  1600.          FCBFQQ      TERMINAL
  1601.          FILEMODES
  1602.  
  1603.      5.  INTEGER4 type
  1604.  
  1605.          BYLONG      LOWORD
  1606.          FLOATLONG   MAXINT4
  1607.          HIWORD      ROUNDLONG
  1608.          INTEGER4    TRUNCLONG
  1609.  
  1610.      6.  Super array type
  1611.  
  1612.          LSTRING
  1613.          NULL
  1614.          STRING
  1615.  
  1616.      7.  WORD type
  1617.  
  1618.          MAXWORD
  1619.          WORD
  1620.          WRD
  1621.  
  1622.      8  Miscellaneous
  1623.  
  1624.          ADRMEM      INTEGER2
  1625.          ADSMEM      REAL4
  1626.          BYTE        REAL8
  1627.          INTEGER1    SINT
  1628.  
  1629.  
  1630.  
  1631.  Chapter 5  Introduction to Data Types
  1632.  
  1633.  ───────────────────────────────────────────────────────────────────────────
  1634.  
  1635.  5.1  What Is a Type?
  1636.  
  1637.  5.2  Declaring Data Types
  1638.  
  1639.  5.3  Type Compatibility
  1640.  
  1641.        5.3.1  Type Identity and Reference Parameters
  1642.  
  1643.        5.3.2  Type Compatibility and Expressions
  1644.  
  1645.        5.3.3  Assignment Compatibility
  1646.  
  1647.  
  1648.  
  1649.  Types in Microsoft Pascal fall into three broad categories: simple,
  1650.  structured, and reference types. Table 5.1 that follows gives a breakdown
  1651.  of the types in each of these groups. The remainder of this chapter
  1652.  discusses types in general; Chapters 6 through 9 discuss the different
  1653.  groups in detail.
  1654.  
  1655.  
  1656.  5.1  What Is a Type?
  1657.  
  1658.  
  1659.  A type is the set of values that a variable or value can have within a
  1660.  program. Types are either predeclared or declared explicitly.
  1661.  
  1662.  For example, the types INTEGER and REAL are predeclared, while the
  1663.  type ARRAY [1..10] OF INTEGER is declared explicitly. An explicitly
  1664.  declared type may also be given a type identifier. To accomplish this
  1665.  latter task, a type declaration is required.
  1666.  
  1667.  
  1668.  Table 5.1
  1669.  Catagories  of Types in Microsoft Pascal
  1670. ╓┌───────────┌─────────────────────────┌─────────────────────────────────────╖
  1671.  Category    Includes                  Comments/Examples
  1672.  ───────────────────────────────────────────────────────────────────────────
  1673.  Simple      Ordinal types
  1674.  Types         INTEGER                 -MAXINT..MAXINT
  1675.                WORD                    0..MAXWORD
  1676.                CHAR                    CHR(0)..CHR(255)
  1677.                BOOLEAN                 (FALSE,TRUE)
  1678.                enumerated types        e.g., (RED,BLUE)
  1679.                subrange types          e.g., 100..5000
  1680.              REAL4, REAL8
  1681.              INTEGER4                  -MAXINT4..MAXINT4
  1682.  Category    Includes                  Comments/Examples
  1683.             INTEGER4                  -MAXINT4..MAXINT4
  1684.  
  1685.  Structured  ARRAY OF type
  1686.  Types         general (OF any type)
  1687.                SUPER ARRAY (OF type)
  1688.                  STRING (n)            [1..n] of CHAR
  1689.                  LSTRING (n)           [0..n] of CHAR
  1690.              RECORD
  1691.              SET OF type
  1692.              FILE OF
  1693.                general (binary) files
  1694.                TEXT                    Like FILE OF CHAR
  1695.  
  1696.  Reference   Pointer Types             e.g., ^TREETIP
  1697.  Types         ADR OF type             Relative address
  1698.                ADS OF type             Segmented address
  1699.  
  1700.  Procedural                            Only as parameter
  1701.  and                                   type
  1702.  Functional
  1703.  Category    Includes                  Comments/Examples
  1704. Functional
  1705.  Types
  1706.  
  1707.  
  1708.  5.2  Declaring Data Types
  1709.  
  1710.  
  1711.  The type declaration associates an identifier with a type of value.
  1712.  You declare types in the TYPE section of a program, procedure, function,
  1713.  module, interface, or implementation (not in the heading of a procedure or
  1714.  function).
  1715.  
  1716.  A type declaration consists of an identifier followed by an equal sign
  1717.  and a type clause.
  1718.  
  1719.  Examples of type definitions:
  1720.  
  1721.      TYPE LINE = STRING (80);
  1722.           PAGE = RECORD
  1723.                PAGENUM : 1..499;
  1724.                LINES : ARRAY [1..60] OF LINE;
  1725.                FACE : (LEFT, RIGHT);
  1726.                NEXTPAGE : ^PAGE
  1727.                END;
  1728.  
  1729.  After declaring the data types, you declare variables of the types
  1730.  just defined in the VAR section of a program, procedure, function, module,
  1731.  or interface, or in the heading of a procedure or function. The following
  1732.  sample VAR section declares variables of the types in the preceding sample
  1733.  TYPE section:
  1734.  
  1735.      VAR PARAGRAPH : LINE;
  1736.          BOOK : PAGE;
  1737.  
  1738.  Because a type identifier is not defined until its declaration is
  1739.  processed by the compiler, a recursive type declaration such as the
  1740.  following is illegal:
  1741.  
  1742.      T = ARRAY [0..9] OF T;
  1743.  
  1744.  Reference types require a  standard exception to this rule and are
  1745.  discussed in Chapter 9, "Reference and Other Types."
  1746.  
  1747.  A special feature of MS-Pascal is a category called super types. A
  1748.  super type declaration determines the set of types that designators of that
  1749.  super type can assume; it also associates an identifier with the super
  1750.  type. Super type declarations also occur in the TYPE section. The only
  1751.  super types currently available in MS-Pascal are super arrays.
  1752.  
  1753.  
  1754.  5.3  Type Compatibility
  1755.  
  1756.  
  1757.  MS-Pascal follows the ISO standard for type compatibility, with some
  1758.  additional rules added for super array types, LSTRINGs, and constant
  1759.  coercions (i.e., forced changes in the type of a constant). Type transfer
  1760.  functions, to override the typing rules, are available with some MS-Pascal
  1761.  features.
  1762.  
  1763.  Two types can be "identical," "compatible," or "incompatible." An
  1764.  expression may or may not be "assignment compatible" with a variable, value
  1765.  parameter, or array index.
  1766.  
  1767.  
  1768.  5.3.1  Type Identity and Reference Parameters
  1769.  
  1770.  
  1771.  Two types are identical if they have the identical identifier or if the
  1772.  identifiers are declared equivalent with a type definition like the
  1773.  following:
  1774.  
  1775.      TYPE T1 = T2;
  1776.  
  1777.  "Identical" types are truly identical in MS-Pascal: there is no
  1778.  difference between types T1 and T2 in the example above. Type identity is
  1779.  based on the name of the types, and not on the way they are declared or
  1780.  structured. Thus, for example, T1 and T2 are not identical in the following
  1781.  declarations:
  1782.  
  1783.      TYPE T1 = ARRAY [1..10] OF CHAR;
  1784.           T2 = ARRAY [1..10] OF CHAR;
  1785.  
  1786.  Actual and formal reference parameters must be of identical types.
  1787.  Or, if a formal reference parameter is of a super array type, the actual
  1788.  parameter must be of the same super array type or a type derived from it.
  1789.  Two record or array types must be identical for assignment.
  1790.  
  1791.  The only exception is for strings. Here, actual parameters of type
  1792.  CHAR, STRING, STRING (n), LSTRING, and LSTRING (n) are compatible with a
  1793.  formal parameter super array type STRING. Also, the type of a string
  1794.  constant will change to any LSTRING type with a large enough bound. For
  1795.  example, the type of 'ABC' will change to LSTRING (5) if necessary.
  1796.  
  1797.  Furthermore, an actual parameter of any FILE type may be passed to a
  1798.  formal parameter of a special record type FCBFQQ. Similarly, an actual
  1799.  parameter of type FCBFQQ may be passed to a formal parameter of any file
  1800.  type. See Section 8.7, "File I/O: System Level," for a description of
  1801.  the FCBFQQ type.
  1802.  
  1803.  STRING (n) is a shorthand notation for:
  1804.  
  1805.      PACKED ARRAY [1..n] OF CHAR
  1806.  
  1807.  The two types are identical. However, because variables with the type
  1808.  LSTRING are treated specially in assignments, comparisons, READs, and
  1809.  WRITEs, LSTRING (n) is not a shorthand notation for PACKED ARRAY [0..n] OF
  1810.  CHAR. The two types are not identical, compatible, or assignment
  1811.  compatible. See Section 7.2.3, "Using STRINGs and LSTRINGs," for further
  1812.  information on string types.
  1813.  
  1814.  
  1815.  5.3.2  Type Compatibility and Expressions
  1816.  
  1817.  
  1818.  Two simple or reference types are compatible if any of the following is
  1819.  true:
  1820.  
  1821.      1.  They are identical.
  1822.  
  1823.      2.  They are both ADR types.
  1824.  
  1825.      3.  They are both ADS types.
  1826.  
  1827.      4.  One is a subrange of the other.
  1828.  
  1829.      5.  They are subranges of compatible types.
  1830.  
  1831.  Two structured types are compatible if any of the following is true:
  1832.  
  1833.      1.  They are identical.
  1834.  
  1835.      2.  They are SET types with compatible base types.
  1836.  
  1837.      3.  They are STRING derived types of equal length.
  1838.  
  1839.      4.  They are LSTRING derived types.
  1840.  
  1841.  However, two structured types are incompatible if any of the following is
  1842.  true:
  1843.  
  1844.      1.  Either type is a FILE or contains a FILE.
  1845.  
  1846.      2.  Either type is a super array type.
  1847.  
  1848.      3.  One type is PACKED and the other is not.
  1849.  
  1850.  Two values must be of compatible types when combined with an operator
  1851.  in an expression. (Most operators have additional limitations on the type
  1852.  of their operands. See Chapter 12, "Expressions," for details.) A CASE
  1853.  index expression type must be compatible with all CASE constant values.
  1854.  
  1855.  
  1856.  5.3.3  Assignment Compatibility
  1857.  
  1858.  
  1859.  Some types are implicitly compatible. This permits assignment across
  1860.  type boundaries. For instance, assume you declare the following variables:
  1861.  
  1862.      VAR DESTINATION : T_DEST;
  1863.          SOURCE : T_SOURCE;
  1864.  
  1865.  SOURCE is assignment compatible with DESTINATION (i.e.,
  1866.  DESTINATION := SOURCE is permitted) if one of the following is true:
  1867.  
  1868.      1.  T_SOURCE and T_DEST are identical types.
  1869.  
  1870.      2.  T_SOURCE and T_DEST are compatible and SOURCE has a value in the
  1871.          range of subrange type T_DEST.
  1872.  
  1873.      3.  T_DEST is of type REAL and T_SOURCE is compatible with type INTEGER
  1874.          or INTEGER4.
  1875.  
  1876.      4.  T_DEST is of type INTEGER4 and T_SOURCE is compatible with type
  1877.          INTEGER or WORD.
  1878.  
  1879.  Also, if T_DEST and T_SOURCE are compatible structured types, then SOURCE
  1880.  is assignment compatible with DESTINATION if one of the following is true:
  1881.  
  1882.      1.  For SETs, every member of SOURCE is in the base type of T_DEST.
  1883.  
  1884.      2.  For LSTRINGs, UPPER (DESTINATION) >= SOURCE.LEN.
  1885.  
  1886.  Other than in the assignment statement itself, assignment compatibility
  1887.  is required in the following cases of implicit assignment:
  1888.  
  1889.      1.  passing value parameters
  1890.  
  1891.      2.  READ and READLN procedures
  1892.  
  1893.      3.  control variable and limits in a FOR statement
  1894.  
  1895.      4.  super array type array bounds, and array indices
  1896.  
  1897.  Assignment compatibility is usually known at compile time, and an
  1898.  assignment generates simple instructions. However, some subrange, set, and
  1899.  LSTRING assignments depend on the value of the expression to be assigned
  1900.  and thus cannot be checked until runtime. If the range checking switch is
  1901.  on, assignment compatibility is checked at runtime; otherwise, no checking
  1902.  is done.
  1903.  
  1904.  
  1905.  
  1906.  Chapter 6  Simple Types
  1907.  
  1908.  ───────────────────────────────────────────────────────────────────────────
  1909.  
  1910.  6.1  Ordinal Types
  1911.  
  1912.        6.1.1  INTEGER
  1913.  
  1914.        6.1.2  WORD
  1915.  
  1916.        6.1.3  CHAR
  1917.  
  1918.        6.1.4  BOOLEAN
  1919.  
  1920.        6.1.5  Enumerated Types
  1921.  
  1922.        6.1.6  Subrange Types
  1923.  
  1924.  6.2  REAL
  1925.  
  1926.  6.3  INTEGER4
  1927.  
  1928.  
  1929.  
  1930.  The basic distinction between simple and structured data types is that
  1931.  simple types cannot be divided into other types, while structured types
  1932.  (discussed in Chapter 7, "Arrays, Records, and Sets," and Chapter 8,
  1933.  "Files") are composed of other types. The simple data types fall into
  1934.  three categories:
  1935.  
  1936.      1.  ordinal types
  1937.  
  1938.      2.  REAL
  1939.  
  1940.      3.  INTEGER4
  1941.  
  1942.  
  1943.  6.1  Ordinal Types
  1944.  
  1945.  
  1946.  Ordinal types are all finite and countable. They include the following
  1947.  simple types:
  1948.  
  1949.       INTEGER
  1950.       WORD
  1951.       CHAR
  1952.       BOOLEAN
  1953.       enumerated types
  1954.       subrange types
  1955.  
  1956.  INTEGER4, though finite and countable, is not an ordinal type.
  1957.  
  1958.  
  1959.  6.1.1  INTEGER
  1960.  
  1961.  
  1962.  INTEGER values are a subset of the whole numbers and range from -MAXINT
  1963.  through 0 to MAXINT. MAXINT is the predeclared constant 32767 (i.e.,
  1964.  2^15 - 1) for current Microsoft Pascal target machines. (The value -32768
  1965.  is not a valid INTEGER; the compiler uses it to check for uninitialized
  1966.  INTEGER and INTEGER subrange variables.)
  1967.  
  1968.  INTEGER is not a subrange of INTEGER4 (discussed in Section 6.3,
  1969.  "INTEGER4"). If it were, signed expressions would have to be calculated
  1970.  using the INTEGER4 type and the result converted to INTEGER.
  1971.  
  1972.  Expressions are always calculated using a base type, not a subrange
  1973.  type. INTEGER type constants may be changed internally to WORD type if
  1974.  necessary, but INTEGER variables cannot. INTEGER values change to REAL or
  1975.  INTEGER4 in an expression, if necessary, but not to WORD. The ORD function
  1976.  converts a value of any ordinal type to an INTEGER type.
  1977.  
  1978.  The predeclared type INTEGER2 is identical to INTEGER.
  1979.  
  1980.  
  1981.  6.1.2  WORD
  1982.  
  1983.  
  1984.  The WORD and INTEGER types are similar, differing chiefly in their
  1985.  range of values. Both are ordinal types. You can think of WORD values as
  1986.  either a group of 16 bits or as a subset of the whole numbers from 0 to
  1987.  MAXWORD (65535, i.e., 2^16 - 1). The WORD type is an MS-Pascal feature
  1988.  that is useful in several ways:
  1989.  
  1990.      1.  to express values in the range from 32768 to 65535
  1991.  
  1992.      2.  to operate on machine addresses
  1993.  
  1994.      3.  to perform primitive machine operations, such as word ANDing and
  1995.          word shifting, without using the INTEGER type and running into the
  1996.          -32768 value
  1997.  
  1998.  Unlike INTEGERs, all WORDs are nonnegative values. The WRD function
  1999.  changes any ordinal type value to WORD type. Like INTEGER values, WORD
  2000.  values in an expression are converted to the INTEGER4 type, if necessary.
  2001.  
  2002.  Having both an INTEGER and a WORD type permits mapping of 16-bit
  2003.  quantities in either of two ways:
  2004.  
  2005.      1.  as a signed value ranging from -32767 to +32767
  2006.  
  2007.      2.  as a positive value ranging from 0 to 65535.
  2008.  
  2009.  However, you must not mix WORD and INTEGER values in an expression
  2010.  (although doing so generates a warning rather than an error message). WORD
  2011.  and INTEGER values are not assignment compatible either.
  2012.  
  2013.  
  2014.  6.1.3  CHAR
  2015.  
  2016.  
  2017.  In MS-Pascal, CHAR values are 8-bit ASCII values. CHAR is an ordinal
  2018.  type. All 256-byte values are included in the type CHAR. In addition,
  2019.  SET OF CHAR is supported. Relational comparisons use the ASCII collating
  2020.  sequence.
  2021.  
  2022.  Although the line-marker character used in TEXT files is not part of
  2023.  the CHAR type in the ISO standard, some target operating systems for
  2024.  MS-Pascal may require the line-marker character to be included (e.g.,
  2025.  carriage return).
  2026.  
  2027.  The CHR function changes any ordinal type value to CHAR type, as long
  2028.  as ORD of the value is in the range from 0 to 255. See Appendix D, "ASCII
  2029.  Character Codes," for a complete listing of the ASCII character set.
  2030.  
  2031.  
  2032.  6.1.4  BOOLEAN
  2033.  
  2034.  
  2035.  BOOLEAN is an ordinal type with only two (predeclared) values: FALSE
  2036.  and TRUE. The BOOLEAN type is a special case of an enumerated type,
  2037.  where ORD (FALSE) is 0 and ORD (TRUE) is 1. This means that FALSE < TRUE.
  2038.  
  2039.  You may redefine the identifiers BOOLEAN, FALSE, and TRUE, but the
  2040.  compiler implicitly uses the ordinal (default) type in Boolean expressions
  2041.  and in IF, REPEAT, and WHILE statements.
  2042.  
  2043.  No function exists for changing an ordinal type value to a BOOLEAN
  2044.  type value. However, you can achieve this effect with the ODD function for
  2045.  INTEGER and WORD values, or the expression:
  2046.  
  2047.       ORD (value) <> 0
  2048.  
  2049.  
  2050.  6.1.5  Enumerated Types
  2051.  
  2052.  
  2053.  An enumerated type defines an ordered set of values. These values are
  2054.  constants and are enumerated by the identifiers that denote them.
  2055.  
  2056.  Examples of enumerated type declarations:
  2057.  
  2058.       FLAGCOLOR = (RED, WHITE, BLUE)
  2059.       SUITS = (CLUB, DIAMOND, HEART, SPADE)
  2060.       DOGS = (MAUDE, EMILY, BRENDAN)
  2061.  
  2062.  Every enumerated type is also an ordinal type. Identifiers for all
  2063.  enumerated type constants must be unique within their declaration level.
  2064.  
  2065.  At the extend level, the READ and WRITE procedures and the ENCODE
  2066.  and DECODE functions operate on values of an enumerated type by treating
  2067.  the actual constant identifier as a string. This means that enumerated
  2068.  values can be read directly.
  2069.  
  2070.  The ORD function, at the standard level, can be used to change
  2071.  enumerated values into INTEGER values; the WRD function changes enumerated
  2072.  values into WORD values.
  2073.  
  2074.  The RETYPE function, at system level, can be used to change INTEGER or
  2075.  WORD values to an enumerated type. For example:
  2076.  
  2077.       IF RETYPE (COLOR, I) = BLUE THEN WRITELN ('TRUE BLUE')
  2078.  
  2079.  The values obtained by applying the ORD function to the constants of
  2080.  an enumerated type always begin with zero. Thus, the values obtained for
  2081.  the type FLAGCOLOR, from the example above, are as follows:
  2082.  
  2083.       ORD (RED) = 0
  2084.       ORD (WHITE) = 1
  2085.       ORD (BLUE) = 2
  2086.  
  2087.  Enumerated types are particularly useful for representing an abstract
  2088.  collection of names, such as names for operations or commands. Modifying a
  2089.  program by adding a new value to an enumerated type is much safer than
  2090.  using raw numbers, since any arrays indexed with the type or sets based on
  2091.  the type are changed automatically.
  2092.  
  2093.  For example, interactive input of a command might be accomplished by
  2094.  reading the enumerated type identifier that corresponds to a command.
  2095.  Since enumerated types are ordered, comparisons like RED < GREEN may also
  2096.  be useful. At times, access to the lowest and highest values of the
  2097.  enumerated type is useful with the LOWER and UPPER functions, as in the
  2098.  following example:
  2099.  
  2100.      VAR TINT : COLOR;
  2101.      FOR TINT := LOWER (TINT) TO UPPER (TINT)
  2102.         DO PAINT (TINT)
  2103.  
  2104.  
  2105.  6.1.6  Subrange Types
  2106.  
  2107.  
  2108.  A subrange type is a subset of an ordinal type. The type from which the
  2109.  subset is taken is called the "host" type. Therefore, all subrange
  2110.  types are also ordinal types.
  2111.  
  2112.  You can define a subrange type by giving the lower and upper bounds of
  2113.  the subrange (in that order). The lower bound must not be greater than the
  2114.  upper bound, but the bounds may be equal. The subrange type is frequently
  2115.  used as the index type of an array bound or as the base type of a set. See
  2116.  Chapter 7, "Arrays, Records, and Sets," for a discussion of arrays and
  2117.  sets.
  2118.  
  2119.  Examples of subranges along with their host ordinal type:
  2120.  
  2121.      Host Ordinal        Subrange
  2122.  ───────────────────────────────────────────────────────────────────────────
  2123.      INTEGER             100..200
  2124.      WORD                WRD(1)..9
  2125.      CHAR                'A'..'Z'
  2126.      enumerated type     RED..YELLOW
  2127.  
  2128.  In addition, you may substitute a subrange clause for a list of values
  2129.  in the following circumstances:
  2130.  
  2131.      1.  when setting constants
  2132.  
  2133.      2.  when setting constructors
  2134.  
  2135.      3.  when setting CASE statement constants and record variant labels (at
  2136.          the extend level)
  2137.  
  2138.  Besides using the subrange type in array and set declarations, you can
  2139.  use it to help guarantee that the value of a variable is within acceptable
  2140.  bounds. If the range checking switch is on during compilation, these
  2141.  bounds are checked at runtime.
  2142.  
  2143.  For instance, if the logic of a program implies that a variable always
  2144.  has a value from 100 to 999, then declaring it with a subrange causes the
  2145.  compiler to check that the variable is never assigned a value outside this
  2146.  range.
  2147.  
  2148.  In addition, declaring a subrange type may permit the compiler to
  2149.  allocate less room and use simpler operations. For example, declaring
  2150.  BOTTLES to be the INTEGER subrange 1..100 means that the type can be
  2151.  allocated in eight bits instead of sixteen.
  2152.  
  2153.  Three subrange types are predeclared:
  2154.  
  2155.      1.  BYTE = WRD(0)..255;
  2156.          {8-bit WORD subrange}
  2157.  
  2158.      2.  SINT = -127..127;
  2159.          {8-bit INTEGER subrange}
  2160.  
  2161.      3.  INTEGER1 = SINT
  2162.  
  2163.  The BYTE type is particularly useful in machine-oriented applications.
  2164.  For example, the ADRMEM and ADSMEM types (see Section 9.1.2, "Address
  2165.  Types," for details) normally treat memory as an array of bytes. However,
  2166.  since the BYTE type is really a subrange of the WORD type, expressions with
  2167.  BYTE values are calculated using 16-bit instead of 8-bit arithmetic, if
  2168.  necessary.
  2169.  
  2170.  In some cases (for example, an assignment of a BYTE expression to a
  2171.  BYTE variable when the math checking switch is off), the compiler can
  2172.  optimize 16-bit arithmetic to 8-bit arithmetic. In general, using BYTE
  2173.  instead of WORD saves memory at the expense of BYTE-to-WORD conversions in
  2174.  expression calculations.
  2175.  
  2176.  At the extend level, subrange bounds can be constant expressions.
  2177.  Because the compiler assumes that the left parenthesis always starts an
  2178.  enumerated type declaration, the first expression in a subrange declaration
  2179.  must not start with a left parenthesis. For example:
  2180.  
  2181.       TYPE {First two are permitted.}
  2182.              FEE = (A, B, C);
  2183.              FIE = M + 2 * N .. (P - 2) * N;
  2184.              {FOO is invalid as declared.}
  2185.              FOO = (M + 2) * N .. P - 2 * N;
  2186.  
  2187.  
  2188.  6.2  REAL
  2189.  
  2190.  
  2191.  REAL values are nonordinal values of a given range and precision; the
  2192.  range of allowable values depends on the target system. Refer to the
  2193.  Microsoft Pascal Compiler User's Guide for more specific information about
  2194.  your system.
  2195.  
  2196.  Most MS-Pascal implementations use either the Microsoft or IEEE single
  2197.  precision real number format. These formats have a 24-bit mantissa and an
  2198.  8-bit exponent, giving about seven digits of precision and a maximum value
  2199.  of 1.701411E38. Microsoft format REAL constants are limited to the range
  2200.  1.0E-38 to 1.0E+38. There is also a decimal real format (controlled by the
  2201.  $DECMATH metacommand).
  2202.  
  2203.  The current version of MS-Pascal includes expanded numeric data types
  2204.  for processing higher precision real (and integer) numbers. For reals, this
  2205.  includes support for single and double precision real numbers according to
  2206.  the IEEE floating-point standard, as well as single and double precision
  2207.  decimal-format numbers.
  2208.  
  2209.  Standard Pascal provides a type REAL. MS-Pascal provides three real
  2210.  types: REAL, REAL4, and REAL8. However, the type REAL is always identical
  2211.  to either REAL4 or REAL8. The choice is made with a metacommand, $real:n,
  2212.  where n is either 4 or 8. {$real:8} has the same effect as TYPE REAL =
  2213.  REAL8. The default type for REAL is normally REAL4, but may be changed.
  2214.  See Appendix B, "Version Specifics," in the Microsoft Pascal Compiler
  2215.  User's Guide for details.
  2216.  
  2217.  Any or all of these real number forms may be used in a single program.
  2218.  However, programs that use REAL4 and REAL8 will not be portable.
  2219.  
  2220.  The REAL4 type is in 32-bit IEEE format, and the REAL8 type is in 64-
  2221.  bit IEEE format. The IEEE standard format is as follows:
  2222.  
  2223.       REAL4       Sign bit, 8-bit binary exponent with
  2224.                   bias of 127, 23-bit mantissa
  2225.  
  2226.       REAL8       Sign bit, 11-bit binary exponent with
  2227.                   bias of 1023, 52-bit mantissa
  2228.  
  2229.  In both cases the mantissa has a "hidden" most significant bit (always one)
  2230.  and represents a number greater than or equal to 1.0 but less than 2.0. An
  2231.  exponent of zero means a value of zero, and the maximum exponent means a
  2232.  value called NAN ("Not A Number"). Bytes are in "reverse" order; the
  2233.  lowest addressed byte is the least significant mantissa byte.
  2234.  
  2235.  The REAL4 numeric range is barely seven significant digits (24 bits),
  2236.  with an exponent range of E-38 to E+38. The REAL8 numeric range includes
  2237.  over fifteen significant digits (53 bits), with an exponent range of E-306
  2238.  to E+306 (a very large number!).
  2239.  
  2240.  The exponent character can be "D" or "d" as well as "E" or "e", so a
  2241.  number like 12.34d56 is permitted. This minor extension provides
  2242.  compatibility with other Microsoft languages. However, the D or d exponent
  2243.  character does not indicate double precision (as it does in FORTRAN), since
  2244.  this would imply that numbers with E or e exponent characters are single
  2245.  precision.
  2246.  
  2247.  REAL literals in MS-Pascal are converted first to REAL8 format and
  2248.  then to REAL4 as necessary (for example, to be passed as a CONST parameter
  2249.  or to initialize a variable in a VALUE section). If you need actual REAL4
  2250.  constants, you must declare them as REAL4 variables (perhaps adding the
  2251.  READONLY attribute) and assign them a constant in a VALUE section.
  2252.  
  2253.  Both REAL4 and REAL8 values are passed to intrinsic functions as
  2254.  reference (CONSTS) parameters, rather than as value parameters. The
  2255.  compiler accepts REAL expressions as CONSTS parameters;  it will evaluate
  2256.  the expression, assign the result to a stack temporary, and pass the
  2257.  address of the temporary, which is usually more efficient than passing the
  2258.  value itself (especially in the REAL8 case).
  2259.  
  2260.  Functions that return REAL values use the long return method; that is,
  2261.  the caller passes an additional, hidden, offset address of a stack
  2262.  temporary which will receive the result. This applies to all functions
  2263.  returning REAL4 or REAL8 values, both user-defined and intrinsic. See
  2264.  Section 12.2, "Boolean Expressions," for a description of REAL comparisons
  2265.  that produce an unordered result.
  2266.  
  2267.  The MS-Pascal runtime libraries provide additional REAL functions
  2268.  to support Microsoft FORTRAN. These functions are available in MS-Pascal,
  2269.  but are not predeclared. See Chapter 15, "Available Procedures and
  2270.  Functions," for further information on the functions available and how to
  2271.  use them.
  2272.  
  2273.  Base ten representation of REAL data is supported by Microsoft Pascal
  2274.  using a floating-point format. It consists of 6 (single) and 14 (double)
  2275.  binary coded decimal digits packed two to a byte. (If the exponent byte is
  2276.  zero, the number is zero). For information on the allowable ranges for
  2277.  single and double precision numbers, see Section 9.2, "Internal
  2278.  Representations of Data Types," in the Microsoft Pascal Compiler User's
  2279.  Guide.
  2280.  
  2281.  
  2282.  6.3  INTEGER4
  2283.  
  2284.  
  2285.  Like INTEGER and WORD values, INTEGER4 values are a subset of the whole
  2286.  numbers. INTEGER4 values range from -MAXLONG to MAXLONG. MAXLONG is a
  2287.  predeclared constant with the value of 2,147,483,647 (i.e., 2^31 - 1). The
  2288.  value -2,147,487,648 (i.e., -2^31) is not a valid INTEGER4.
  2289.  
  2290.  Unlike INTEGER and WORD, the INTEGER4 type is not considered an
  2291.  ordinal type. There are no INTEGER4 subranges and INTEGER4 cannot be an
  2292.  array index or the base type of a set. Also, INTEGER4 values cannot be
  2293.  used to control FOR and CASE statements.
  2294.  
  2295.  INTEGER4 is currently an extended numeric type, like REAL. Values of
  2296.  type INTEGER or WORD in an expression change automatically to INTEGER4 if
  2297.  the expression requires an intermediate value that is out of the range of
  2298.  either INTEGER or WORD. Values of type INTEGER4 do not change to REAL in
  2299.  an expression; you must explicitly use the FLOATLONG function to make the
  2300.  conversion.
  2301.  
  2302.  
  2303.  
  2304.  Chapter 7  Arrays, Records, and Sets
  2305.  
  2306.  ───────────────────────────────────────────────────────────────────────────
  2307.  
  2308.  7.1  Arrays
  2309.  
  2310.  7.2  Super Arrays
  2311.  
  2312.        7.2.1  STRINGs
  2313.  
  2314.        7.2.2  LSTRINGs
  2315.  
  2316.        7.2.3  Using STRINGs and LSTRINGs
  2317.  
  2318.  7.3  Records
  2319.  
  2320.        7.3.1  Variant Records
  2321.  
  2322.        7.3.2  Explicit Field Offsets
  2323.  
  2324.  7.4  Sets
  2325.  
  2326.  
  2327.  
  2328.  A structured type is composed of other types. The components of
  2329.  structured types are either simple types or other structured types. A
  2330.  structured type is characterized by the types of its components and by its
  2331.  structuring method. In Microsoft Pascal, a structured type can occupy up to
  2332.  65534 bytes of memory.
  2333.  
  2334.  The structured types in MS-Pascal are the following:
  2335.  
  2336.       ARRAY <range> OF <type>
  2337.       SUPER ARRAY <range> OF <type>
  2338.         STRING  (n)
  2339.         LSTRING (n)
  2340.       RECORD
  2341.       SET OF <base-type>
  2342.       FILE OF <type>
  2343.  
  2344.  Because components of structures can be structured types themselves, you
  2345.  may have, for example, an array of arrays, a file of records containing
  2346.  sets, or a record containing a file and another record. This is an example
  2347.  of the data typing flexibility that provides Pascal with much of its
  2348.  linguistic power as a computing language.
  2349.  
  2350.  The remainder of this chapter discusses arrays, records, and sets.
  2351.  See Chapter 8, "Files," for a discussion of files.
  2352.  
  2353.  
  2354.  7.1  Arrays
  2355.  
  2356.  
  2357.  An array type is a structure that consists of a fixed number of
  2358.  components. All of the components are of the same type (called the
  2359.  "component type").
  2360.  
  2361.  The elements of the array are designated by indices, which are values
  2362.  of the "index type" of the array. The index type must be an ordinal type:
  2363.  BOOLEAN, CHAR, INTEGER, WORD, subrange, or enumerated.
  2364.  
  2365.  Arrays in Pascal are one-dimensional, but since the component type can
  2366.  also be an array, n-dimensional arrays are supported as well.
  2367.  
  2368.  Examples of type declarations for arrays:
  2369.  
  2370.       TYPE
  2371.       INT_ARRAY : ARRAY [1..10] OF INTEGER;
  2372.       ARRAY_2D : ARRAY [0..7] OF ARRAY [0..8] OF 0..9;
  2373.       MORAL_RAY : ARRAY [PEOPLE] OF (GOOD, EVIL)
  2374.  
  2375.  In the last declaration, PEOPLE is a subrange type, while GOOD and EVIL are
  2376.  enumerated constants.
  2377.  
  2378.  A short-hand notation available for n-dimensional arrays makes the
  2379.  following statement the same as the second example in the preceding
  2380.  paragraph:
  2381.  
  2382.       ARRAY_2D : ARRAY [0..7, 0..8] OF 0..9;
  2383.  
  2384.  After declaring these arrays, you could assign to components of the
  2385.  arrays with statements such as these:
  2386.  
  2387.       INT_ARRAY [10] := 1234;
  2388.       ARRAY_2D [0,99] := 9;
  2389.       MORAL_RAY [Machiavelli] := EVIL;
  2390.  
  2391.  All of an n-dimensional PACKED array is packed; therefore these statements
  2392.  are equivalent:
  2393.  
  2394.       PACKED ARRAY [1..2, 3..4] OF REAL
  2395.       PACKED ARRAY [1..2] OF PACKED ARRAY [3..4] OF REAL
  2396.  
  2397.  See Chapter 9, "Reference and Other Types," for a discussion of packed
  2398.  types.
  2399.  
  2400.  
  2401.  7.2  Super Arrays
  2402.  
  2403.  
  2404.  A super array is an example of an MS-Pascal "super type."  A super type
  2405.  is like a set of types or like a function that returns a type. Super types
  2406.  in general, and super arrays in particular, are features of MS-Pascal.
  2407.  
  2408.  The super array type has several important uses. You may use it for
  2409.  any of the following purposes:
  2410.  
  2411.      1.  To process strings. Both STRING and LSTRING are predeclared super
  2412.          array types. The LSTRING type handles variable length strings.
  2413.          STRING handles fixed-length strings and strings more than 255
  2414.          characters long.
  2415.  
  2416.      2.  To dynamically allocate arrays of varying sizes. Otherwise such
  2417.          arrays would need a maximum possible size allocation.
  2418.  
  2419.      3.  As the formal parameter type in a procedure or function. Such a
  2420.          declaration makes the procedure or function usable for a set or
  2421.          class of types, rather than for just a single fixed-length type.
  2422.  
  2423.  A super type identifier specifies the set of types represented by the
  2424.  super type. A later type declaration may declare a normal type identifier
  2425.  as a type "derived" from that class of types. This derived type is like any
  2426.  other type.
  2427.  
  2428.  A super array type declaration is an array type declaration prefixed
  2429.  with the keyword SUPER. Every array upper bound is replaced with an
  2430.  asterisk, as shown:
  2431.  
  2432.       TYPE VECTOR = SUPER ARRAY [1..*] OF REAL;
  2433.  
  2434.  Following the preceding type declaration, you could declare the following
  2435.  variables:
  2436.  
  2437.       VAR ROW : VECTOR (10);
  2438.           COL : VECTOR (30);
  2439.           ROWP : ^VECTOR;
  2440.  
  2441.  In this example, VECTOR is a super array type identifier. VECTOR (10) and
  2442.  VECTOR (30) are type designators denoting "derived types." ROW and COL are
  2443.  variables of types derived from VECTOR. ROWP is a pointer to the super
  2444.  array type VECTOR.
  2445.  
  2446.  Although the general concept of super types allows other "types of
  2447.  types," such as super subranges and super sets (in addition to super
  2448.  arrays), super types currently allow only an array type with parametric
  2449.  upper bounds. A super type is a class of types and not a specific type.
  2450.  Thus, in the VAR section of a program, procedure, or function, you cannot
  2451.  declare the variables to be of a super type; you must declare them as
  2452.  variables of a type derived from the super type.
  2453.  
  2454.  However, a formal reference parameter in a procedure or function can
  2455.  be given a super type: this allows the routine to operate on any of the
  2456.  possible derived types. (This kind of parameter is called a "conformant
  2457.  array" in other Pascals.)
  2458.  
  2459.  A pointer referent type can also be given a super type. This allows a
  2460.  pointer to refer to any of the possible derived types. A pointer referent
  2461.  to a super type allows "dynamic arrays." These arrays are allocated on the
  2462.  heap by passing their upper bound to the procedure NEW. See Chapter 9,
  2463.  "Reference and Other Types," for a discussion of pointer types and dynamic
  2464.  allocation. See Chapter 15, "Available Procedures and Functions," for a
  2465.  description of the procedure NEW.
  2466.  
  2467.  Example using the NEW procedure for dynamic allocation:
  2468.  
  2469.       VAR STR_CRT : ^SUPER PACKED ARRAY [1..*] OF CHAR;
  2470.             VEC_CRT : ^SUPER ARRAY [0..*, 0..*] OF REAL;
  2471.               .
  2472.               .
  2473.             NEW (STR_CRT, 12);
  2474.             NEW (VEC_CRT, 9, 99);
  2475.  
  2476.  An actual parameter in a procedure or function can be of a super type
  2477.  rather than a derived type, but only if the parameter is a reference
  2478.  parameter or pointer referent. (These are the only kinds of variables that
  2479.  can be of a super rather than a derived type.)
  2480.  
  2481.  Example of super arrays:
  2482.  
  2483.  
  2484.       TYPE VECTOR = SUPER ARRAY [1..*] OF REAL;
  2485.       {"VECTOR" is the super array type identifier.}
  2486.  
  2487.       VAR X : VECTOR (12); Y : VECTOR (24); Z : VECTOR (36);
  2488.       {X, Y, and Z are types derived from VECTOR.}
  2489.  
  2490.       {Below, SUM accepts variables of all types}
  2491.       {derived from the super type VECTOR.}
  2492.       FUNCTION SUM (VAR V : VECTOR) : REAL;
  2493.       {V is the formal reference parameter of the}
  2494.       {super type VECTOR.}
  2495.  
  2496.       VAR S : REAL; I : INTEGER;
  2497.       BEGIN
  2498.         S := 0;
  2499.         FOR I := 1 TO UPPER (V) DO S := S + V [I];
  2500.         SUM := S
  2501.       END;
  2502.  
  2503.       BEGIN
  2504.         .
  2505.         .
  2506.         TOTAL := SUM (X) + SUM (Y) + SUM (Z);
  2507.         .
  2508.         .
  2509.       END
  2510.  
  2511.  The normal type rules for components of a super array type and for
  2512.  type designators that use a super array type allow components to be
  2513.  assigned, compared, and passed as parameters.
  2514.  
  2515.  The UPPER function returns the actual upper bound of a super array
  2516.  parameter or referent. The maximum upper bound of a type derived from a
  2517.  super array type is limited to the maximum value of the index type implied
  2518.  by the lower bound (e.g., MAXINT, MAXWORD). Two super array types are
  2519.  predeclared, STRING and LSTRING. The compiler directly supports STRING and
  2520.  LSTRING types in the following ways:
  2521.  
  2522.      1.  LSTRING and STRING assignment
  2523.  
  2524.      2.  LSTRING and STRING comparison
  2525.  
  2526.      3.  LSTRING and STRING READs
  2527.  
  2528.      4.  access to the length of a STRING with the UPPER function
  2529.  
  2530.      5.  access to maximum length of an LSTRING with the UPPER function
  2531.  
  2532.      6.  access to LSTRING length with STR.LEN and STR[0]
  2533.  
  2534.  These subjects are discussed in Section 7.2.3, "Using STRINGs AND
  2535.  LSTRINGs."
  2536.  
  2537.  
  2538.  7.2.1  STRINGs
  2539.  
  2540.  
  2541.  STRINGs are predeclared super arrays of characters:
  2542.  
  2543.       TYPE STRING  = SUPER PACKED ARRAY [1..*] OF CHAR;
  2544.  
  2545.  A string literal such as 'abcdefg' automatically has the type STRING (n).
  2546.  The size of the array 'abcdefg' is 7; thus, the constant is of the STRING
  2547.  derived type, STRING (7).
  2548.  
  2549.  Standard Pascal calls any packed array of characters with a lower
  2550.  bound of one a "string" and permits a few special operations on this type
  2551.  (such as comparison and writing) that you cannot do with other arrays.
  2552.  
  2553.  In MS-Pascal, the super array notation STRING (n) is identical to
  2554.  PACKED ARRAY [1..n] OF CHAR (n may range from 1 to MAXINT). There is no
  2555.  default for n, as in some other Pascals, since STRING means the super array
  2556.  type itself and not a string with a default length.
  2557.  
  2558.  The identifier STRING is for a super array, so you can only use it as
  2559.  a formal reference parameter type or pointer referent type. The other
  2560.  super array restrictions apply: You may not compare such a parameter or
  2561.  dereferenced pointer or assign it as a whole.
  2562.  
  2563.  Any variable (or constant) with the super array type STRING, or one of
  2564.  the types CHAR or STRING (n) or PACKED ARRAY [1..n] OF CHAR, can be passed
  2565.  to a formal reference parameter of super array type STRING. Furthermore, a
  2566.  variable of type LSTRING or LSTRING (n) can also be passed to a formal
  2567.  reference parameter of type STRING. For a discussion of STRING as a formal
  2568.  reference parameter, see Section 7.2.3, "Using STRINGs and LSTRINGs."
  2569.  
  2570.  Standard Pascal supports the assigning, comparing, and writing of
  2571.  STRINGs. The extend level permits reading STRINGs, including the super
  2572.  array type STRING and a derived type STRING (n). Reading a STRING causes
  2573.  input of characters until the end of a line or the end of the STRING is
  2574.  reached. If the end of the line is reached first, the rest of the STRING is
  2575.  filled with blanks. Writing a string writes all of its characters.
  2576.  
  2577.  The customary Pascal type compatibility rules are relaxed for STRINGs.
  2578.  Any two variables or constants with the type PACKED ARRAY [1..n] OF CHAR or
  2579.  the type STRING (n) can be compared or assigned if the lengths are equal.
  2580.  However, since the length of a STRING super array type may vary,
  2581.  comparisons and assignments are not allowed.
  2582.  
  2583.  Example of an illegal STRING assignment:
  2584.  
  2585.       PROCEDURE CANNOT_DO (VAR S : STRING);
  2586.       VAR STR : STRING (10);
  2587.       BEGIN
  2588.         STR := S
  2589.         {This assignment is illegal because}
  2590.         {the length of S may vary.}
  2591.       END;
  2592.  
  2593.  The PACKED prefix in the declaration PACKED ARRAY [1..n] OF CHAR, as
  2594.  defined in the ISO standard, normally implies that a component cannot be
  2595.  passed as a reference parameter. In MS-Pascal, this restriction does not
  2596.  apply.
  2597.  
  2598.  To keep conformance to the ISO standard, this passing of the CHAR
  2599.  component of a STRING as a reference parameter is defined as an "error not
  2600.  caught." Also, the index type of a string is officially INTEGER, but WORD
  2601.  type values can also be used to index a STRING. Many string-processing
  2602.  applications are expected to take advantage of the LSTRING type, described
  2603.  in Section 7.2.2, "LSTRINGs."
  2604.  
  2605.  A number of intrinsic procedures and functions for strings are
  2606.  discussed in Chapter 15, "Available Procedures and Functions." Many of the
  2607.  procedures and functions described work on STRINGs; some apply only to
  2608.  LSTRINGs.
  2609.  
  2610.  
  2611.  7.2.2  LSTRINGs
  2612.  
  2613.  
  2614.  The LSTRING feature in MS-Pascal allows variable-length strings.
  2615.  LSTRING (n) is predeclared as:
  2616.  
  2617.       TYPE LSTRING = SUPER PACKED ARRAY [0..*] OF CHAR
  2618.  
  2619.  However, a variable with the explicit type PACKED ARRAY [0..n] OF CHAR is
  2620.  not "identical" to the type LSTRING (n) even though they are structurally
  2621.  the same. There is no default for n; the range of n is from zero to 255.
  2622.  Characters in an LSTRING can be accessed with the usual array notation.
  2623.  
  2624.  Internally, LSTRINGs contain a length (L), followed by a string of
  2625.  characters. The length is contained in element zero of the LSTRING and can
  2626.  vary from 0 to the upper bound. The length of an LSTRING variable T can be
  2627.  accessed as T[0] with type CHAR, or as T.LEN with type BYTE. String
  2628.  constants of type CHAR or STRING (n) are changed automatically to type
  2629.  LSTRING.
  2630.  
  2631.  The predeclared constant NULL is the empty string, LSTRING (0).
  2632.  NULL is the only constant with type LSTRING; there is no way to define
  2633.  other LSTRING constants. As with STRINGs, a CHAR component of an LSTRING
  2634.  can be passed as a reference parameter, and  WORD and INTEGER values can be
  2635.  used to index an LSTRING.
  2636.  
  2637.  Several operations work differently on LSTRINGs than on STRINGs.
  2638.  Any LSTRING can be assigned to any other LSTRING, so long as the current
  2639.  length of the right side is not greater than the maximum length of the left
  2640.  side. Similarly, an LSTRING can be passed as a value parameter to a
  2641.  procedure or function, so long as the current length of the actual
  2642.  parameter is not greater than the maximum length specified by the formal
  2643.  parameter. If the range checking switch is on, the compiler checks the
  2644.  assignment of LSTRINGs and the passing of LSTRING (n) parameters. The
  2645.  actual number of bytes assigned or passed is the minimum of the upper
  2646.  bounds of the LSTRINGs.
  2647.  
  2648.  Neither side in an LSTRING assignment can be a parameter of the super
  2649.  array type LSTRING; both must be types derived from it.
  2650.  
  2651.  Examples of LSTRING assignments:
  2652.  
  2653.       {Declaring the variables}
  2654.       VAR A : LSTRING (19);
  2655.           B : LSTRING (14);
  2656.           C : LSTRING (6);
  2657.             .
  2658.             .
  2659.       {Assigning the variables}
  2660.       A := '19 character string';
  2661.       B := '14 characters';
  2662.       C := 'shorty';
  2663.       A := B;
  2664.       {This is legal, since the length of B}
  2665.       {is less than the maximum length of A.}
  2666.       C := A;
  2667.       {This is illegal, since length of A}
  2668.       {is greater than the maximum length of C.}
  2669.  
  2670.  You may compare any two LSTRINGs, including super array type LSTRINGs (the
  2671.  only super array type comparison allowed). Reading an LSTRING variable
  2672.  causes input of characters, until the end of the current line or the end of
  2673.  the LSTRING, and sets the length to the number of characters read. Writing
  2674.  from an LSTRING writes the current length string.
  2675.  
  2676.  
  2677.  7.2.3  Using STRINGs and LSTRINGs
  2678.  
  2679.  
  2680.  This section describes the STRING and LSTRING operations directly supported
  2681.  by the compiler. An annotated program at the end of this section
  2682.  illustrates the use of STRINGs and LSTRINGs in context.
  2683.  
  2684.  See also Chapter 15, "Available Procedures and Functions," for
  2685.  descriptions of the following string procedures and functions:
  2686.  
  2687.       CONCAT      INSERT
  2688.       COPYLST     POSITN
  2689.       COPYSTR     SCANEQ
  2690.       DELETE      SCANNE
  2691.  
  2692.  At the system level of MS-Pascal, the procedures FILLC, FILLSC, MOVEL,
  2693.  MOVESL, MOVER, and MOVESR also operate on strings.
  2694.  
  2695.  MS-Pascal supports STRINGs and LSTRINGs directly in the following
  2696.  ways:
  2697.  
  2698.   1.  Assignment
  2699.  
  2700.       You may assign any LSTRING value to any LSTRING variable, as long
  2701.       as the maximum length of the target variable is greater than or
  2702.       equal to thecurrent length of the source value and neither is the
  2703.       super array type LSTRING. If the maximum length of the target is
  2704.       less than the current length of the source, only the target length
  2705.       is assigned, and a runtime error occurs if the range checking
  2706.       switch is on. You may assign a STRING value to a STRING variable,
  2707.       as long as the length of both sides is the same and neither side is
  2708.       the super array type STRING. Passing either STRING or LSTRING as a
  2709.       value parameter is much like making an assignment.
  2710.  
  2711.   2.  Comparison
  2712.  
  2713.       The LSTRING operators <  <=  >  >=  <>  = use the length byte for
  2714.       string comparisons; the operands may be of different lengths. Two
  2715.       strings must be the same length to be considered equal. If two strings
  2716.       of different lengths are equal up to the length of the shorter one,
  2717.       the shorter is considered less than the longer one. The operands can
  2718.       be of the super array type LSTRING. For STRINGs, the same relational
  2719.       operators are available, but the lengths must be the same and operands
  2720.       of the super array type STRINGs are not allowed.
  2721.  
  2722.   3.  READs and WRITEs
  2723.  
  2724.       READ LSTRING reads until the LSTRING is filled or until the end-of-
  2725.       line is found. The current length is set to the number of characters
  2726.       read. WRITE LSTRING uses the current length. See also READSET
  2727.       (described in Chapter 16, "File-Oriented Procedures and Functions"),
  2728.       which reads into an LSTRING as long as input characters are in a given
  2729.       SET OF CHAR. READ STRING pads with spaces if the line is shorter than
  2730.       the STRING. WRITE STRING writes all the characters in the string.
  2731.       Both READ and WRITE permit the super array types STRING and LSTRING,
  2732.       as well as their derived types.
  2733.  
  2734.  
  2735.   4.  Length access
  2736.  
  2737.       You can access the current length of an LSTRING variable T with
  2738.       T.LEN, which is of type BYTE, or with T[0], which is of type CHAR.
  2739.       This notation can assign a new length, as well as determine the
  2740.       current length. The UPPER function will find the maximum length of an
  2741.       LSTRING or the length of a STRING. This is especially useful for
  2742.       finding the upper bound of a super array reference parameter or
  2743.       pointer referent.
  2744.  
  2745.  You cannot assign or compare mixed STRINGs and LSTRINGs, unless the
  2746.  STRING is constant. You can assign STRINGs to LSTRINGs, or vice versa,
  2747.  with one of the move routines or with the COPYSTR and COPYLST procedures.
  2748.  Since constants of type STRING or CHAR change automatically to type LSTRING
  2749.  if necessary, LSTRING constants are considered normal STRING constants.
  2750.  NULL (the zero length LSTRING) is the only explicit LSTRING constant.
  2751.  
  2752.  In the sample program at the end of this section, all STRING
  2753.  parameters (CONST or VAR) may take either a STRING or an LSTRING; all
  2754.  LSTRING parameters are VAR LSTRING and must take an LSTRING variable.
  2755.  
  2756.  A "special transformation" lets you pass an actual LSTRING parameter
  2757.  to a formal reference parameter of type STRING. The length of the formal
  2758.  STRING is the actual length of the LSTRING. Therefore, if LSTR (in the
  2759.  following example) is of type LSTRING (n) or LSTRING, it can be passed to a
  2760.  procedure or function with a formal reference parameter of type STRING:
  2761.  
  2762.       VAR LSTR : LSTRING (10);
  2763.         .
  2764.         .
  2765.       PROCEDURE TIE_STRING (VAR STR : STRING);
  2766.         .
  2767.         .
  2768.       TIE_STRING (LSTR);
  2769.  
  2770.  In this case, UPPER (STR) is equivalent to LSTR.LEN.
  2771.  
  2772.  Procedures and functions with reference parameters of super type
  2773.  STRING can operate equally well on STRINGs and LSTRINGs. The only reason to
  2774.  declare a parameter of type LSTRING is when the length must be changed.
  2775.  Normally, an LSTRING is either a VAR or a VARS parameter in a procedure or
  2776.  function, since a CONST or CONSTS parameter of type LSTRING cannot be
  2777.  changed.
  2778.  
  2779.  Example of a program that uses STRINGs and LSTRINGs:
  2780.  
  2781.       PROGRAM STRING_SAMPLE;
  2782.  
  2783.       PROCEDURE STRING_PROC  (CONST S : STRING);  BEGIN END;
  2784.       PROCEDURE LSTRING_PROC (CONST S : LSTRING);  BEGIN END;
  2785.  
  2786.       VAR
  2787.         CHR1VAR : CHAR;
  2788.         STR5VAR : STRING (5);
  2789.         LST5VAR : LSTRING (5);
  2790.         LST9VAR : LSTRING (9);
  2791.         STR4VAR : PACKED ARRAY [1..4] OF CHAR;
  2792.         STR6VAR : PACKED ARRAY [1..6] OF CHAR;
  2793.  
  2794.       BEGIN
  2795.  
  2796.       {Look at all the kinds of strings a}
  2797.       {CONST STRING parameter takes.}
  2798.       STRING_PROC ('A');
  2799.       {Character constant is OK.}
  2800.       STRING_PROC (CHR1VAR);
  2801.       {Character variable is OK.}
  2802.       STRING_PROC ('STRING');
  2803.       {STRING constant is OK.}
  2804.       STRING_PROC (STR5VAR);
  2805.       {STRING variable is OK.}
  2806.       STRING_PROC (LST5VAR);
  2807.       {LSTRING variable is OK.}
  2808.  
  2809.       {However, a CONST LSTRING parameter cannot take}
  2810.       {non-LSTRING variables.}
  2811.       LSTRING_PROC ('A');
  2812.       {Character constant is OK.}
  2813.       LSTRING_PROC (CHR1VAR);
  2814.       {Character variable is not OK!}
  2815.       LSTRING_PROC ('STRING');
  2816.       {STRING constant is OK.}
  2817.       LSTRING_PROC (STR5VAR);
  2818.       {STRING variable is not OK!}
  2819.       LSTRING_PROC (LST5VAR);
  2820.       {LSTRING variable is OK.}
  2821.  
  2822.       {Assignments to a STRING variable are limited}
  2823.       {to the same type.}
  2824.       STR5VAR := 'A';
  2825.       {Character constant is not OK!}
  2826.       STR5VAR := CHR1VAR;
  2827.       {Character variable is not OK!}
  2828.       STR5VAR := 'TINY';
  2829.       {STRING constant is too small.}
  2830.       STR5VAR := 'RIGHT';
  2831.       {Both sides have five characters; OK.}
  2832.       STR5VAR := 'longer';
  2833.       {Not OK; STRING constant is too large.}
  2834.       STR5VAR := LST5VAR;
  2835.       {Not OK; you cannot assign LSTRINGs to STRINGs.}
  2836.       COPYSTR (LST5VAR, STR5VAR);
  2837.       {COPYSTR is an intrinsic procedure.}
  2838.       STR5VAR := STR4VAR;
  2839.       {Not OK; STRING variable is too small.}
  2840.       COPYSTR (STR4VAR, STR5VAR);
  2841.       {COPYSTR is OK; padding of space in STR5VAR[5].}
  2842.       STR5VAR := STR5VAR;
  2843.       {OK; both sides have five characters.}
  2844.       STR5VAR := STR6VAR;
  2845.       {Not OK; STRING variable is too large.}
  2846.  
  2847.       {Assignments to an LSTRING variable, however,}
  2848.       {are more flexible.}
  2849.       LST5VAR := 'A';
  2850.       {Character constant is OK.}
  2851.       LST5VAR := CHR1VAR;
  2852.       {Character variable is not OK!}
  2853.       LST5VAR := 'TINY';
  2854.       {Smaller STRING constant is OK.}
  2855.       LST5VAR := 'RIGHT';
  2856.       {Same length STRING constant is OK.}
  2857.       LST5VAR := 'LONGER';
  2858.       {This gives an error at runtime only; OK for now.}
  2859.       LST5VAR := LST9VAR;
  2860.       {This may give an error at runtime; OK for now.}
  2861.       LST9VAR := LST5VAR;
  2862.       {This isn't even checked at runtime; always OK.}
  2863.       LST5VAR := STR5VAR;
  2864.       {Not OK; you cannot assign a STRING variable to an}
  2865.       {LSTRING variable.}
  2866.       COPYLST (STR5VAR, LST5VAR)
  2867.       {This is the way to copy a STRING variable}
  2868.       {to an LSTRING.}
  2869.  
  2870.  END.
  2871.  
  2872.  
  2873.  7.3  Records
  2874.  
  2875.  
  2876.  A record structure acts as a template for conceptually related data of
  2877.  different types. The record type itself is a structure consisting of a
  2878.  fixed number of components, usually of different types.
  2879.  
  2880.  Each component of a record type is called a field. The definition of a
  2881.  record type specifies the type and an identifier for each field within the
  2882.  record. Because the scope of these "field identifiers" is the record
  2883.  definition itself, they must be unique within the declaration. The field
  2884.  values associated with field identifiers are accessible with record
  2885.  notation or with the WITH statement.
  2886.  
  2887.  For example, you could declare the following record type:
  2888.  
  2889.       TYPE LP = RECORD
  2890.                 TITLE : LSTRING (100);
  2891.                 ARTIST : LSTRING (100);
  2892.                 PLASTIC : ARRAY
  2893.                   [1..SONG_NUMBER] OF SONG_TITLE
  2894.                 END
  2895.  
  2896.  You could then declare a variable of the type LP, as follows:
  2897.  
  2898.       VAR BEATLES_1 : LP;
  2899.  
  2900.  Finally, you could access a component of the record with either field
  2901.  notation or the WITH statement (note the period separating field
  2902.  identifiers):
  2903.  
  2904.       BEATLES_1.TITLE := 'Meet The Beatles';
  2905.       WITH BEATLES_1 DO
  2906.          PLASTIC[1] := 'I Wanna Hold Your Hand'
  2907.  
  2908.  
  2909.  7.3.1  Variant Records
  2910.  
  2911.  
  2912.  A record may have several "variants," in which case a certain field
  2913.  called the "tag field" indicates which variant to use. The tag field
  2914.  may or may not have an identifier and storage in the record. Some
  2915.  operations, such as the NEW and DISPOSE procedures and the SIZEOF function,
  2916.  can specify a tag value even if the tag is not stored as part of the
  2917.  record.
  2918.  
  2919.  Examples of variant records:
  2920.  
  2921.       TYPE OBJECT = RECORD
  2922.              X, Y : REAL;
  2923.              CASE S : SHAPE OF
  2924.                SQUARE : (SIZE, ANGLE : REAL);
  2925.                CIRCLE : (DIAMETER : REAL)
  2926.           END;
  2927.  
  2928.           FOO = RECORD
  2929.             CASE BOOLEAN OF
  2930.               TRUE : (I, J : INTEGER);
  2931.               FALSE : (CASE COLOR OF
  2932.                      BLUE : (X : REAL);
  2933.                      RED : (Y : INTEGER4))
  2934.           END;
  2935.  
  2936.  Only one variant part per record is allowed; it must be the last field of
  2937.  the record. However, this variant part can also have a variant (and so on,
  2938.  to any level). All field identifiers in a given record type must be
  2939.  unique, even in different variants. For example, after declaring the
  2940.  record types above, you could create and then assign to the variables shown
  2941.  in the following example:
  2942.  
  2943.       VAR O, P : OBJECT;
  2944.           F, G : FOO;
  2945.  
  2946.       BEGIN
  2947.         O.DIAMETER := 12.34;  {CASE of CIRCLE}
  2948.         P.SIZE := 1.2;        {CASE of SQUARE}
  2949.         F.I := 1; F.J := 2;   {CASE of TRUE}
  2950.         G.X := 123.45;       {CASE of FALSE and BLUE}
  2951.         G.Y := 678999         {CASE of FALSE and RED;}
  2952.                               {this overwrites G.X.}
  2953.       END;
  2954.  
  2955.  The latest ISO standard requires every possible tag field value to select
  2956.  some variant. Therefore, it is illegal to include CASE INTEGER OF and omit
  2957.  a variant for every possible INTEGER value. However, such an omission is an
  2958.  error not caught in MS-Pascal.
  2959.  
  2960.  MS-Pascal supports the use of full CASE constant options in the variant
  2961.  clause; that is, a list of constants can define a case. At the
  2962.  extend level, subranges and the OTHERWISE statement can also define a case.
  2963.  If used, OTHERWISE applies to the last variant in the list and is not
  2964.  followed by a colon. You can also declare an empty variant, such as
  2965.  POINT:() or OTHERWISE (). You can even declare an entirely empty
  2966.  record type, although the compiler issues a warning whenever the record
  2967.  is used.
  2968.  
  2969.  The ISO standard defines a number of errors that relate to variant
  2970.  records; these errors may not be caught in MS-Pascal, even if the tag-
  2971.  checking switch is on. (The tag-checking switch generates code each time a
  2972.  variant field is used, to check that the tag value is correct.)  In the
  2973.  record type declaration of OBJECT (in the previous example), any use of
  2974.  SIZE generates a check that S = SQUARE. However, in the case of FOO, uses
  2975.  of "I" cannot be checked because MS-Pascal does not allocate the BOOLEAN
  2976.  tag field.
  2977.  
  2978.  The ISO standard further declares that when a "change of variant"
  2979.  occurs (such as when a new tag value is assigned), all the variant fields
  2980.  become undefined. However, MS-Pascal does not set the fields to an
  2981.  uninitialized value when a new tag is assigned. Therefore, using a variant
  2982.  field with an undefined value is an error not caught in MS-Pascal.
  2983.  
  2984.  Nor does MS-Pascal enforce various restrictions on a record variable
  2985.  allocated on the heap with the long form of the NEW procedure. See Chapter
  2986.  15, "Available Procedures and Functions," for details. However, MS-Pascal
  2987.  does check an assignment to such a "short record" to see that only the
  2988.  short record itself is modified in the heap.
  2989.  
  2990.  A record allocated with the long form of NEW may be released using the
  2991.  short form of DISPOSE with no ill effects (this is an ISO error not caught
  2992.  in MS-Pascal). It is also an error not caught in MS-Pascal to DISPOSE of a
  2993.  record passed as a reference parameter or used by an active WITH statement.
  2994.  
  2995.  Variant records interact with MS-Pascal features in two ways:
  2996.  
  2997.      1.  Declaring a variant that contains a file is not safe; any change to
  2998.          the file's data using a field in another variant may lead to I/O
  2999.          errors, even if the file is closed. In the following example, any
  3000.          use of R will lead to errors in F:
  3001.  
  3002.               RECORD CASE BOOLEAN OF
  3003.                   TRUE : (F : FILE OF REAL);
  3004.                   FALSE : (R : ARRAY [1..100] OF REAL)
  3005.                   END;
  3006.  
  3007.      2.  Giving initial data to several overlapping variants in a variable
  3008.          in a VALUE section could have unpredictable results. In the
  3009.          following example, the initial value of LAP is uncertain:
  3010.  
  3011.               VAR LAP : RECORD CASE BOOLEAN OF
  3012.                   TRUE : (I : INTEGER4);
  3013.                   FALSE : (R : REAL)
  3014.                   END;
  3015.               VALUE LAP.I := 10; LAP.R := 1.5;
  3016.  
  3017.  MS-Pascal generates a warning message if you attempt either of these
  3018.  operations.
  3019.  
  3020.  
  3021.  7.3.2  Explicit Field Offsets
  3022.  
  3023.  
  3024.  MS-Pascal lets you assign explicit byte offsets to the fields in a
  3025.  record. This system level feature can be useful for interfacing to
  3026.  software in other languages, since control block formats may not conform to
  3027.  the usual MS-Pascal field allocation method. However, because it also
  3028.  permits unsafe operations, such as overlapping fields and word values at
  3029.  odd byte boundaries, it is not recommended unless the interface is
  3030.  necessary.
  3031.  
  3032.  Example showing assignment of explicit byte offsets:
  3033.  
  3034.       TYPE CPM = RECORD
  3035.                    NDRIVE [00] : BYTE;
  3036.                    FILENM [01] : STRING (8);
  3037.                    FILEXT [09] : STRING (3);
  3038.                    EXTENT [12] : BYTE;
  3039.                    CPMRES [13] : STRING (20);
  3040.                    RECNUM [33] : WORD;
  3041.                    RECOVF [35] : BYTE
  3042.                  END;
  3043.  
  3044.          OVERLAP = RECORD
  3045.                    BYTEAR [00] : ARRAY [0..7] OF BYTE;
  3046.                    WORDAR [00] : ARRAY [0..3] OF WORD;
  3047.                    BITSAR [00] : SET OF 0..63
  3048.                  END;
  3049.  
  3050.  As may be seen in the example, the offset is enclosed in brackets; this is
  3051.  similar to attribute notation. The number is the byte offset to the start
  3052.  of the field. Some target machines may not permit accessing a 16-bit value
  3053.  at an odd address, but the MS-Pascal Compiler doesn't catch this as an
  3054.  error.
  3055.  
  3056.  If you give any field an offset, give offsets to all fields. For any
  3057.  offset that you omit, the compiler picks an arbitrary value. Although the
  3058.  compiler will process a declaration that includes both offsets and variant
  3059.  fields, you should use only one or the other in a given program.
  3060.  
  3061.  Although you can completely control field overlap with explicit
  3062.  offsets, variants provide the long forms of the procedures NEW, DISPOSE,
  3063.  and SIZEOF. If you want to allocate different length records, use the
  3064.  RETYPE and GETHQQ procedures, instead of variants and the long form of NEW.
  3065.  For example:
  3066.  
  3067.       CPMPV := RETYPE (CPMP, GETHQQ (36));
  3068.  
  3069.  The compiler does support structured constants for record types with
  3070.  explicit offsets. Internally, odd length fields greater than one are
  3071.  rounded to the next even length. For example:
  3072.  
  3073.       ODDR = RECORD
  3074.                F1[00] : STRING (3);
  3075.                F2[03] : CHAR
  3076.              END;
  3077.  
  3078.  In this example, field F1 is four bytes long, so an assignment to F1
  3079.  overwrites F2. In such a record, all odd length fields must be assigned
  3080.  first.
  3081.  
  3082.  
  3083.  7.4  Sets
  3084.  
  3085.  
  3086.  A set type defines the range of values that a set may assume. This
  3087.  range of assumable values is the "power set" of the base type you specify
  3088.  in the type definition. The power set is the set of all possible sets that
  3089.  could be composed from an ordinal base type. The null set, [], is a member
  3090.  of every set.
  3091.  
  3092.  Suppose you declare the following set types:
  3093.  
  3094.       TYPE HUES = SET OF COLOR;
  3095.            CAPS = SET OF 'A'..'Z';
  3096.            MATTER = SET OF (ANIMAL, VEGETABLE, MINERAL);
  3097.  
  3098.  Then you declare variables like the following:
  3099.  
  3100.       VAR FLAG : HUES;
  3101.           VOWELS : CAPS;
  3102.           LIVE : MATTER;
  3103.  
  3104.  Finally, you could assign these set variables:
  3105.  
  3106.       FLAG := [RED, WHITE, BLUE];
  3107.       VOWELS := ['A', 'E', 'I', 'O', 'U'];
  3108.       LIVE := [ANIMAL, VEGETABLE];
  3109.  
  3110.  The set elements must be enclosed in brackets. This practice differs from
  3111.  the use of parentheses to enclose the base enumerated type in a set type
  3112.  declaration.
  3113.  
  3114.  Set operations are implemented directly by generated in-line code or
  3115.  by routines in the set unit. See Chapter 12, "Expressions," for a complete
  3116.  discussion of operations on sets.
  3117.  
  3118.  The ORD value of the base type can range from 0 to 255. Thus, SET OF
  3119.  CHAR is legal, but SET OF 1942..1984 is not.
  3120.  
  3121.  Sets whose maximum ORD value is 15 (i.e., sets that fit into a WORD)
  3122.  are usually more efficient than larger ones. Also, if the range checking
  3123.  switch is on, passing a set as a value parameter invokes a runtime
  3124.  compatibility check, unless the formal and actual sets have the same type.
  3125.  
  3126.  Sets provide a clear and efficient way of giving several qualities or
  3127.  attributes to an object. In another language, you might assign each quality
  3128.  a power of two:
  3129.  
  3130.       READY = 1
  3131.       GETSET = 2
  3132.       ACTIVE = 4
  3133.       DONE = 8
  3134.  
  3135.  You might then assign the qualities with a statement like this:
  3136.  
  3137.       X := (READY + ACTIVE)
  3138.  
  3139.  and then test them using OR and AND as bitwise operators with a statement
  3140.  like:
  3141.  
  3142.       IF ((X AND ACTIVE) <> 0) THEN WRITELN ('GO FISH')
  3143.  
  3144.  The equivalent declaration in MS-Pascal might be:
  3145.  
  3146.       QUALITIES = SET OF (READY, GETSET, ACTIVE, DONE);
  3147.  
  3148.  You could then assign the qualities with X := [ GETSET, ACTIVE] and test
  3149.  them with the following operations:
  3150.  
  3151.       IN          tests a bit
  3152.       +           sets a bit
  3153.       -           clears a bit
  3154.  
  3155.  For  example, an appropriate construction might be:
  3156.  
  3157.       IF ACTIVE IN X THEN WRITELN ('GO FISH')
  3158.  
  3159.  You can also use SET OF 0..15 to test and set the bits in a WORD. Using
  3160.  WORDs both as a set of bits and as the WORD type requires giving two types
  3161.  to the word, with a variant record, the RETYPE function, or an address
  3162.  type.
  3163.  
  3164.  The bits in a set are assigned starting with the most significant bit
  3165.  in the lowest addressed byte. Thus, on a byte-swapped machine, the set [0,
  3166.  7, 8, 15] has the WORD value #80 + #01 + #8000 + #0100.
  3167.  
  3168.  
  3169.  
  3170.  Chapter 8  Files
  3171.  
  3172.  ───────────────────────────────────────────────────────────────────────────
  3173.  
  3174.  8.1  Declaring Files
  3175.  
  3176.  8.2  The Buffer
  3177.  
  3178.  8.3  File Structures
  3179.  
  3180.        8.3.1  BINARY Structure Files
  3181.  
  3182.        8.3.2  ASCII Structure Files
  3183.  
  3184.  8.4  File Access Modes
  3185.  
  3186.        8.4.1  TERMINAL Mode Files
  3187.  
  3188.        8.4.2  SEQUENTIAL Mode Files
  3189.  
  3190.        8.4.3  DIRECT Mode Files
  3191.  
  3192.  8.5  The Predeclared Files: INPUT and OUTPUT
  3193.  
  3194.  8.6  File I/O: Extend Level
  3195.  
  3196.  8.7  File I/O: System Level
  3197.  
  3198.  
  3199.  
  3200.  A file is a structure that consists of a sequence of components, all of
  3201.  the same type. It is through files that Microsoft Pascal interfaces with a
  3202.  given operating system. Therefore, you must understand the FILE type in
  3203.  order to perform input to and output from a program.
  3204.  
  3205.  
  3206.  8.1  Declaring Files
  3207.  
  3208.  
  3209.  As with any other type, you must declare a file variable in order to use
  3210.  it. However, the number of components in a file is not fixed by declaring
  3211.  a FILE type.
  3212.  
  3213.  Examples of FILE declarations:
  3214.  
  3215.       TYPE F1 = FILE OF COLOR;
  3216.            F2 = FILE OF CHAR;
  3217.            F3 = TEXT;
  3218.  
  3219.  Conceptually, a file is simply another data type, like an array, but with
  3220.  no bounds and with only one component accessible at a time. However, a
  3221.  file is usually associated with one of the following:
  3222.  
  3223.      1.  disk files
  3224.  
  3225.      2.  terminals
  3226.  
  3227.      3.  printers
  3228.  
  3229.      4.  other input and output devices
  3230.  
  3231.  This implies the following restriction in MS-Pascal: a FILE OF FILE is
  3232.  illegal, directly or indirectly. Other structures, such as a FILE OF ARRAYs
  3233.  or an ARRAY OF FILEs, are permitted.
  3234.  
  3235.  Most Pascal implementations connect file variables to the data files
  3236.  of the operating system. MS-Pascal always uses the target operating system
  3237.  to access files but does not impose additional formatting or structure on
  3238.  operating system files.
  3239.  
  3240.  MS-Pascal supports normal statically allocated files, files as local
  3241.  variables (allocated on the stack), and files as pointer referents
  3242.  (allocated on the heap). Except for files in super arrays, the compiler
  3243.  generates code to initialize a file when it is allocated and to CLOSE a
  3244.  file when it is deallocated.
  3245.  
  3246.  This initialization call occurs automatically in most cases. However,
  3247.  a file declared in a module or uninitialized unit's interface will only get
  3248.  its initialization call if you call the module or unit identifier as a
  3249.  procedure. File declarations in such cases get the following compiler
  3250.  warning:
  3251.  
  3252.       Contains file initialize module
  3253.  
  3254.  Only a file in an interface of an uninitialized unit does not generate this
  3255.  warning.
  3256.  
  3257.  MS-Pascal sets up the standard files, INPUT and OUTPUT (discussed in
  3258.  Section 8.5, "The Predeclared Files: INPUT and OUTPUT"). In standard
  3259.  Pascal, files must be given in the program header, and when you run your
  3260.  program, the runtime system prompts you for filenames. At the extend
  3261.  level, you may use the ASSIGN and READFN procedures to give explicit
  3262.  operating system filenames to files not included in the program header.
  3263.  
  3264.  Files in record variants or super array types are not recommended; if
  3265.  you use them, the compiler issues a warning. A file variable cannot be
  3266.  assigned, compared, or passed by value: It can only be declared and passed
  3267.  as a reference parameter.
  3268.  
  3269.  At the extend level, you may indicate a file's access method or other
  3270.  characteristics by specifying the mode of the file. The mode is a value of
  3271.  the predeclared enumerated type FILEMODES. The modes available normally
  3272.  include the three base modes, SEQUENTIAL, TERMINAL, and DIRECT. All files,
  3273.  except INPUT and OUTPUT, are given SEQUENTIAL mode by default. INPUT and
  3274.  OUTPUT are given the default mode TERMINAL.
  3275.  
  3276.  
  3277.  8.2  The Buffer
  3278.  
  3279.  
  3280.  Every file F has an associated buffer variable F^. A buffer variable
  3281.  and its associated file might look like this:
  3282.  
  3283.       +---+---+---+---+---+---+
  3284.       | a | b | c | d | e |   |
  3285.       +---+---+---+---+---+---+
  3286.                         ^
  3287.                         | Pointer to current component
  3288.  
  3289.                       +---+
  3290.                       | e |    Buffer variable
  3291.                       +---+
  3292.  
  3293.  The procedures GET and PUT use this buffer variable to READ from and
  3294.  WRITE to files. GET copies the current component of the file to the buffer
  3295.  variable. PUT does the opposite; that is, PUT copies the value of the
  3296.  buffer variable to the current component.
  3297.  
  3298.  The buffer variable can be referenced (i.e., its value fetched or
  3299.  stored) like any other MS-Pascal variable. This allows execution of
  3300.  assignments like the following:
  3301.  
  3302.       F^ := 'z'
  3303.       C := F^
  3304.  
  3305.  A file buffer variable can be passed as a reference parameter to a
  3306.  procedure or function or used as a record in a WITH statement. However, the
  3307.  file buffer variable may not be updated correctly if the file position
  3308.  changes within the procedure, function, or WITH statement. The compiler
  3309.  issues a warning message to alert you to this possibility.
  3310.  
  3311.  For example, the following use of a file buffer variable would generate
  3312.  a warning at compile time:
  3313.  
  3314.       VAR A : TEXT;
  3315.       PROCEDURE CHAR_PROC (VAR X : CHAR);
  3316.         .
  3317.         .
  3318.       CHAR_PROC (A^);
  3319.       {Warning issued here}
  3320.  
  3321.  Two special internal mechanisms in MS-Pascal, lazy evaluation and
  3322.  concurrent I/O, allow, respectively, interactive terminal input in a
  3323.  natural way and overlapped I/O along with program execution. Lazy
  3324.  evaluation is applied to all ASCII structured files and is necessary
  3325.  for natural terminal input. Concurrent I/O is applied to all BINARY
  3326.  structured files and is necessary for some operating systems that
  3327.  support overlapping input and output.
  3328.  
  3329.  Both mechanisms generate a runtime call that is executed before any
  3330.  use of the buffer variable. See Section 16.1.5, "Lazy Evaluation," and
  3331.  Section 16.1.6, "Concurrent I/O," for complete details.
  3332.  
  3333.  
  3334.  8.3  File Structures
  3335.  
  3336.  
  3337.  MS-Pascal files have two basic structures: BINARY and ASCII. These two
  3338.  structures correspond to raw data files and human-readable textfiles,
  3339.  respectively.
  3340.  
  3341.  
  3342.  8.3.1  BINARY Structure Files
  3343.  
  3344.  
  3345.  The Pascal data type FILE OF type corresponds to MS-Pascal BINARY
  3346.  structure files. These, in turn, correspond to unformatted operating
  3347.  system files.
  3348.  
  3349.  Under operating systems that divide files into records, every record
  3350.  is one component of the file type (not to be confused with the record
  3351.  type). Primitive procedures such as GET and PUT operate on a record basis.
  3352.  Under operating systems that do not have their own record structure, the
  3353.  primitive procedures GET and PUT transfer a fixed number of bytes per call,
  3354.  equal to the length of one component. See Section 8.4, "File Access
  3355.  Modes," for further discussion of BINARY files.
  3356.  
  3357.  
  3358.  8.3.2  ASCII Structure Files
  3359.  
  3360.  
  3361.  The Pascal data type TEXT corresponds to MS-Pascal ASCII structure
  3362.  files. These, in turn, correspond to textual operating system files (called
  3363.  "textfiles" in this manual).
  3364.  
  3365.  The Pascal TEXT type is like a FILE OF CHAR, except that groups of
  3366.  characters are organized into "lines" and, to a lesser extent, "pages."
  3367.  Primitive file procedures, such as GET and PUT, always operate on a
  3368.  character basis.
  3369.  
  3370.  However, under operating systems that divide files into records, every
  3371.  record is a line (not a character). Even in operating systems that do not
  3372.  have their own record structure, other languages and utilities have some
  3373.  way of organizing bytes into lines of characters.
  3374.  
  3375.  MS-Pascal provides a number of special functions and procedures that
  3376.  use this line-division feature. Because MS-Pascal does not impose any
  3377.  additional formatting on operating system files of most modes (including
  3378.  SEQUENTIAL, TERMINAL, and DIRECT), programs in other languages can generate
  3379.  and use these files.
  3380.  
  3381.  MS-Pascal textfiles (files of type TEXT) are divided into lines with a
  3382.  "line marker," conceptually a character not of the type CHAR. In theory, a
  3383.  textfile can contain any value of type CHAR. However, under some operating
  3384.  systems, writing a particular character (say, CHR (13), carriage return, or
  3385.  CHR (10), line feed) may terminate the current line (record). This
  3386.  character value is the line marker in this case and, when read, always
  3387.  looks like a blank.
  3388.  
  3389.  Under other operating systems, there may not be a terminating character.
  3390.  Still, as far as you are concerned, every line is followed by a line
  3391.  marker that reads as a blank.
  3392.  
  3393.  At the extend level, a declaration for a textfile may include an optional
  3394.  line length. Setting the line length, which sets record length, is only
  3395.  needed for DIRECT mode textfiles. You may specify line length for other
  3396.  modes as well, but doing so has no effect.
  3397.  
  3398.  Specify the line length of a textfile as a constant in parentheses
  3399.  after the word TEXT:
  3400.  
  3401.       TYPE NAMEADDR = TEXT (128);
  3402.            DEFAULTX = TEXT;
  3403.            SMALLBUF = TEXT (2);
  3404.  
  3405.  
  3406.  8.4  File Access Modes
  3407.  
  3408.  
  3409.  The file modes in MS-Pascal are SEQUENTIAL, TERMINAL, and DIRECT.
  3410.  SEQUENTIAL and TERMINAL mode files are available at the standard level;
  3411.  all three, including DIRECT mode, are available at the extend level.
  3412.  SEQUENTIAL and TERMINAL mode ASCII structure files can have variable length
  3413.  records (lines); DIRECT mode files must have fixed length records or lines.
  3414.  
  3415.  The declaration of a file in Pascal implies its structure, but not its
  3416.  mode. For example, FILE OF STRING (80) indicates BINARY structure; TEXT
  3417.  indicates ASCII structure. An assignment like F.MODE := DIRECT sets the
  3418.  mode; this only works at the extend level and is currently only needed to
  3419.  set DIRECT mode.
  3420.  
  3421.  
  3422.  8.4.1  TERMINAL Mode Files
  3423.  
  3424.  
  3425.  TERMINAL mode files always correspond to an interactive terminal or
  3426.  printer. TERMINAL mode files, like SEQUENTIAL mode files, are opened at the
  3427.  beginning of the file for either reading or writing. Records are accessed
  3428.  one after the other until the end of the file is reached.
  3429.  
  3430.  Operation of TERMINAL mode input for terminals depends on the file
  3431.  structure (ASCII or BINARY). For ASCII structure (type TEXT), entire lines
  3432.  are read at one time. This permits the usual operating system intraline
  3433.  editing, including backspace, advance cursor, and cancel. Characters are
  3434.  echoed to the terminal screen while the line is being typed.
  3435.  
  3436.  If the target operating system does not support intraline editing or
  3437.  echo, the MS-Pascal file system interface provides it. However, since an
  3438.  entire line is read at once, you cannot read the characters as you type
  3439.  them, invoke several prompts and responses on the same line, and so on.
  3440.  
  3441.  For BINARY structure TERMINAL mode (usually type FILE OF CHAR), you
  3442.  can read characters as you type them. No intraline editing or echoing is
  3443.  done. This method permits screen editing, menu selection, and other
  3444.  interactive programming on a keystroke rather than line basis.
  3445.  
  3446.  TERMINAL mode files use lazy evaluation to properly handle normal
  3447.  interactive reading of the terminal keyboard. See Section 16.1.5, "Lazy
  3448.  Evaluation," for details.
  3449.  
  3450.  
  3451.  8.4.2  SEQUENTIAL Mode Files
  3452.  
  3453.  
  3454.  SEQUENTIAL mode files are generally disk files or sequential access
  3455.  devices. Like TERMINAL mode files, SEQUENTIAL mode files are opened at the
  3456.  beginning of the file for either reading or writing, and records are
  3457.  accessed one after another until the end of the file. Standard Pascal
  3458.  files are in SEQUENTIAL mode by default (except for INPUT and OUTPUT).
  3459.  
  3460.  
  3461.  8.4.3  DIRECT Mode Files
  3462.  
  3463.  
  3464.  DIRECT mode files are generally disk files or other random access
  3465.  devices. DIRECT mode files and the ability to specify the access mode for
  3466.  file I/O are available options at the extend level of MS-Pascal.
  3467.  
  3468.  DIRECT mode ASCII structure files, as well as all BINARY structure
  3469.  files, have fixed-length records, where a record is either a line or file
  3470.  component. (Here the term "record" refers not to the normal Pascal record
  3471.  type, but to a disk structuring unit.) DIRECT files are always opened for
  3472.  both reading and writing, and records can be accessed randomly by record
  3473.  number. There is no record number zero; records begin with record number
  3474.  one.
  3475.  
  3476.  
  3477.  8.5  The Predeclared Files: INPUT and OUTPUT
  3478.  
  3479.  
  3480.  Two files, INPUT and OUTPUT, are predeclared in every MS-Pascal
  3481.  program. These files get special treatment as program parameters and are
  3482.  normally required as parameters in the program heading:
  3483.  
  3484.       PROGRAM ACTION (INPUT, OUTPUT);
  3485.  
  3486.  If there are no program parameters and the program does not use the files
  3487.  INPUT and OUTPUT, the heading can look like this:
  3488.  
  3489.       PROGRAM ACTION;
  3490.  
  3491.  However, you should include INPUT and OUTPUT as program parameters if you
  3492.  use them, either explicitly or implicitly, in the program itself:
  3493.  
  3494.        WRITE (OUTPUT, 'Prompt: ')  {Explicit use}
  3495.        WRITE ('Prompt: ')          {Implicit use}
  3496.  
  3497.  These examples would generate a warning if OUTPUT was not declared in the
  3498.  program heading. The only effect of INPUT and OUTPUT as program parameters
  3499.  is to suppress this warning.
  3500.  
  3501.  Although you may redefine the identifiers INPUT and OUTPUT, the file
  3502.  assumed by textfile input and output procedures and functions (e.g., READ,
  3503.  EOLN) is the predeclared definition. The procedures RESET (INPUT) and
  3504.  REWRITE (OUTPUT) are generated automatically, whether or not INPUT and
  3505.  OUTPUT are present as program parameters (you may also use these procedures
  3506.  explicitly).
  3507.  
  3508.  INPUT and OUTPUT have ASCII structure and TERMINAL mode. They are
  3509.  initially connected to your terminal and opened automatically. At the
  3510.  extend level of MS-Pascal, you can change these characteristics if you
  3511.  wish.
  3512.  
  3513.  
  3514.  8.6  File I/O: Extend Level
  3515.  
  3516.  
  3517.  A file variable in MS-Pascal is really a record, of type FCBFQQ, called
  3518.  a file control block. At the extend level, a few standard fields in this
  3519.  record help you handle file modes and error trapping.
  3520.  
  3521.  Additional fields and the record type FCBFQQ itself can be used at the
  3522.  system level, described in Section 8.7, "File I/O: System Level." Along
  3523.  with access to certain FCB fields, extend level I/O also includes the
  3524.  following procedures:
  3525.  
  3526.       ASSIGN      READFN
  3527.       CLOSE       READSET
  3528.       DISCARD     SEEK
  3529.  
  3530.  See Section 16.3, "Extend Level I/O," for a description of these
  3531.  procedures.
  3532.  
  3533.  Use the normal record field syntax to access FCB fields. For a file
  3534.  F, the fields are named F.MODE, F.TRAP, and F.ERRS. You may change or
  3535.  examine these fields at any time.
  3536.  
  3537.  1.  F.MODE : = FILEMODES
  3538.  
  3539.      This field contains the mode of the file: SEQUENTIAL, TERMINAL, or
  3540.      DIRECT. These values are constants of the predeclared enumerated type
  3541.      FILEMODES. The file system uses the MODE field only during RESET and
  3542.      REWRITE. Thus, changing the MODE field of an open file has no effect
  3543.      and is, in fact, discouraged. Except for INPUT and OUTPUT, which have
  3544.      TERMINAL mode, a file's mode is SEQUENTIAL by default.
  3545.  
  3546.      RESET and REWRITE change the mode from SEQUENTIAL to TERMINAL if they
  3547.      discover that the device being opened is a terminal or printer and if
  3548.      the target operating system allows it. This is useful in programs
  3549.      designed to work either interactively or in batch mode. You must set
  3550.      DIRECT mode before RESET or REWRITE if you plan to use SEEK on a file.
  3551.  
  3552.  2.  F.TRAP := BOOLEAN
  3553.  
  3554.      If this field is TRUE, error trapping for file F is turned on. Then,
  3555.      if an input/output error occurs, the program does not abort and
  3556.      the error code can be examined. Initially, F.TRAP is set FALSE. If
  3557.      FALSE and an I/O error occurs, the program aborts.
  3558.  
  3559.  3.  F.ERRS := WRD(0)..15
  3560.  
  3561.      This field contains the error code for file F. An error code of zero
  3562.      means no error; values from 1 to 15  imply an error condition. If you
  3563.      attempt a file operation other than CLOSE or DISCARD and F.ERRS is not
  3564.      zero, the program immediately aborts if F.TRAP is FALSE. If F.TRAP is
  3565.      TRUE and F.ERRS is not zero, the attempted file operation is ignored
  3566.      and the program continues. After the error is trapped, the program
  3567.      must set F.ERRS back to 0 to prevent succeeding file operations from
  3568.      being ignored.
  3569.  
  3570.      CLOSE and DISCARD do not examine the initial value of F.ERRS, so they
  3571.      are never ignored and do not cause an immediate abort. Nevertheless,
  3572.      if CLOSE or DISCARD themselves generate an error condition, F.TRAP is
  3573.      used to determine whether to trap the error or to abort.
  3574.  
  3575.      An operation ignored because of an error condition does not change the
  3576.      file itself, but may change the buffer variable or READ procedure
  3577.      input variables.
  3578.  
  3579.  Also at the extend level, you may set the line length for a textfile,
  3580.  as shown:
  3581.  
  3582.       TYPE SMALLBUF = TEXT (16);
  3583.       VAR RANDOMTEXT : TEXT (132);
  3584.  
  3585.  Declaring line length applies only to DIRECT mode ASCII structure files,
  3586.  where the line length is the record length used for reading and writing.
  3587.  Setting the line length has no effect on other ASCII files.
  3588.  
  3589.  
  3590.  8.7  File I/O: System Level
  3591.  
  3592.  
  3593.  At the system level of MS-Pascal, you can call procedures and functions
  3594.  that have a formal reference parameter of type FCBFQQ with an actual
  3595.  parameter of the type FILE OF type or TEXT, or the identical FCBFQQ type.
  3596.  
  3597.  The FCBFQQ type is the underlying record type used to implement the
  3598.  file type in MS-Pascal. The interface for the target system FCBFQQ type
  3599.  (and any other types needed) is usually part of the internal file system.
  3600.  Thus, procedures and functions that reference FCBFQQ parameters can be
  3601.  called with any file type, including predeclared procedures and functions
  3602.  like CLOSE and READ.
  3603.  
  3604.  An FCBFQQ type variable can be passed to procedures like READLN and
  3605.  WRITELN that require a textfile. This permits, for example, calling
  3606.  directly the interface routines on the target operating system, working
  3607.  with mixtures of MS-Pascal and MS-FORTRAN (which share the file system
  3608.  interface but have special FCBFQQ fields), and other special file system
  3609.  activities.
  3610.  
  3611.  Such activities require a sound knowledge of the file system. See
  3612.  Section 10.2, "An Overview of the File System," in the Microsoft Pascal
  3613.  Compiler User's Guide for a discussion of the file system interface and
  3614.  file control block.
  3615.  
  3616.  
  3617.  
  3618.  Chapter 9  Reference and Other Types
  3619.  
  3620.  ───────────────────────────────────────────────────────────────────────────
  3621.  
  3622.  9.1  Reference Types
  3623.  
  3624.        9.1.1  Pointer Types
  3625.  
  3626.        9.1.2  Address Types
  3627.  
  3628.        9.1.3  Segment Parameters for the Address Types
  3629.  
  3630.        9.1.4  Using the Address Types
  3631.  
  3632.        9.1.5  Notes on Reference Types
  3633.  
  3634.  9.2  PACKED Types
  3635.  
  3636.  9.3  Procedural and Functional Types
  3637.  
  3638.  
  3639.  
  3640.  The array, record, and set types discussed in Chapter 7, "Arrays, Records,
  3641.  and Sets," let you describe data structures whose form and size are
  3642.  predetermined and whose components are accessed in a standard way. The file
  3643.  type, described in Chapter 8, "Files," is a structure that varies in size
  3644.  but whose form and means of access are predetermined.
  3645.  
  3646.  In this chapter, you will find a discussion of reference types, which
  3647.  allow data structures that vary in size and form and whose means of access
  3648.  is particular to the programming problem involved. Also included are notes
  3649.  on PACKED types and procedural and functional types.
  3650.  
  3651.  
  3652.  9.1  Reference Types
  3653.  
  3654.  
  3655.  A reference to a variable or constant is an indirect way to access it. The
  3656.  pointer type is an abstract type for creating, using, and destroying
  3657.  vairables allocated from an area called the heap. The heap is a dynamically
  3658.  growing and shrinking region of memory allocated for pointer variables.
  3659.  
  3660.  Microsoft Pascal also provides two machine-oriented address types: one
  3661.  for addresses that can be representevd in 16 bits, the other for addresses
  3662.  that require 32 bits.
  3663.  
  3664.  Pointers are generally used for trees, graphs, and list processing.
  3665.  Use of pointers is portable, structured, and relatively safe.
  3666.  
  3667.  Address types provide an interface to the hardware and operating
  3668.  system; their use is frequently unstructured, machine specific, low level,
  3669.  and unsafe. Both pointers and address types are dicussed further in the
  3670.  following sections.
  3671.  
  3672.  
  3673.  9.1.1  Pointer Types
  3674.  
  3675.  
  3676.  A pointer type is a set of values that point to variables of a given type.
  3677.  The type of the variables pointed to is called the "reference type.''
  3678.  Reference variables are all dynamically allocated from the heap with the
  3679.  NEW procedure. Pascal variables are normally allocated on the stack or at
  3680.  fixed locations.
  3681.  
  3682.  You may perform only the following actions on pointers:
  3683.  
  3684.      1.  assign them
  3685.  
  3686.      2.  test them for equality and inequality with the two
  3687.          operators = and < >
  3688.  
  3689.      3.  pass them as value or reference parameters
  3690.  
  3691.      4.  dereference them with the up arrow (^)
  3692.  
  3693.  Every pointer type includes the pointer value NIL. Pointers are
  3694.  frequently used to create list structures of records, as shown in the
  3695.  following example:
  3696.  
  3697.  
  3698.       TYPE
  3699.         TREETIP =^TREE
  3700.         TREE = RECORD
  3701.                  VAL : INTEGER;
  3702.                     {Value of TREE cell.}
  3703.                  LEFT, RIGHT : TREETIP
  3704.                     {Pointers to other TREETIP cells.}
  3705.                     {Note recursive definition.}
  3706.                END;
  3707.  
  3708.  Unlike most type declarations, the declaration for a pointer type can
  3709.  refer to a type of which it is itself a component. The declaration can also
  3710.  refer to a type declared later in the same TYPE section, as in TREE and
  3711.  TREETIP in the previous example.
  3712.  
  3713.  Such a declaration is called a forward pointer declaration and
  3714.  permits recursive and mutually recursive structures. Because pointers are
  3715.  so often used in list structures, forward pointer declarations occur
  3716.  frequently.
  3717.  
  3718.  The compiler checks for one ambiguous pointer declaration. Suppose the
  3719.  previous example was in a procedure nested in another procedure that also
  3720.  declared a type TREE. Then the reference type of TREETIP could be either
  3721.  the outer definition or the one following in the same TYPE section. MS-
  3722.  Pascal assumes the TREE type intended is the one later in the same TYPE
  3723.  section and gives the warning:
  3724.  
  3725.       Pointer Type Assumed Forward
  3726.  
  3727.  At the extend level, a pointer can have a super array type as a
  3728.  referent type. The actual upper bounds of the array are passed to the NEW
  3729.  procedure to create a heap variable of the correct size. Forward pointer
  3730.  declarations of the super array type are not allowed.
  3731.  
  3732.  MS-Pascal conforms to the ISO requirement for strict compatibility
  3733.  between pointers. For example, you cannot declare two pointers with
  3734.  different types and then assign or compare them, even if they happen to
  3735.  point to the same underlying type. For example:
  3736.  
  3737.       VAR PRA : ^REAL;
  3738.           PRE : ^REAL;
  3739.       BEGIN PRA := PRE {This is illegal!}
  3740.       END;
  3741.  
  3742.  Programs usually contain only one type declaration for a pointer to a
  3743.  given type. In the TREETIP example, the type of LEFT and RIGHT could be
  3744.  ^TREE instead of TREETIP, but then you couldn't assign variables of type
  3745.  TREETIP to these fields. However, it is sometimes useful to make sure that
  3746.  two classes of pointers are not used together, even if they point to the
  3747.  same type.
  3748.  
  3749.  For example, suppose you have a type RESOURCE kept in a list and
  3750.  declare two types, OWNER and USER, of type ^RESOURCE. The compiler would
  3751.  catch assignment of OWNER values to USER variables and vice versa and issue
  3752.  a warning message.
  3753.  
  3754.  In theory, pointers have nothing to do with actual machine addresses.
  3755.  In fact, a pointer may be implemented in different ways on different target
  3756.  machines. A pointer may be implemented as a normal address, as a segment
  3757.  offset address, as an offset from one or more fixed locations, or as an
  3758.  indirect address, among other possibilities.
  3759.  
  3760.  If the initialization checking switch is on, a newly created pointer
  3761.  has an uninitialized value. If the NIL checking switch is on, pointer
  3762.  values are tested for various invalid values. Invalid values include NIL,
  3763.  uninitialized values, reference to a heap item that has been DISPOSEd, or a
  3764.  value that is not valid as a heap reference.
  3765.  
  3766.  
  3767.  9.1.2  Address Types
  3768.  
  3769.  
  3770.  As a system implementation language, MS-Pascal needs a method of creating,
  3771.  manipulating, and dereferencing actual machine addresses. The pointer type
  3772.  is only applicable to variables in the heap.
  3773.  
  3774.  There are two kinds of addresses: relative and segmented. The
  3775.  keywords ADR and ADS refer to the relative address type and the segmented
  3776.  address type, respectively. As the following example shows, you use the
  3777.  keywords both as type clause prefixes and as prefix operators:
  3778.  
  3779.       VAR INT_VAR : INTEGER;
  3780.           REAL_VAR : REAL;
  3781.           A_INT : ADR OF INTEGER;
  3782.           {Declaration of ADR variable}
  3783.           AS_REAL : ADS OF REAL;
  3784.           {Declaration of ADS variable}
  3785.  
  3786.       BEGIN
  3787.         INT_VAR := 1;
  3788.         {Normal integer variable}
  3789.         REAL_VAR := 3.1415;
  3790.         {Normal real variable}
  3791.         A_INT := ADR INT_VAR;
  3792.         {ADR used as operator}
  3793.         AS_REAL := ADS REAL_VAR;
  3794.         {ADS used as operator}
  3795.         WRITELN (A_INT^, AS_REAL^)
  3796.         {Note use of up arrow to dereference}
  3797.         {the address types.}
  3798.         {Output is 1 and 3.1415.}
  3799.       END.
  3800.  
  3801.  The characteristics of relative and segmented address types, as
  3802.  implemented for different machines, are shown in Table 9.1.
  3803.  
  3804.  
  3805.  Table 9.1.
  3806.  Relative and Segmented Machine Addresses
  3807. ╓┌─────────────────┌─────────────────────┌───────────────────────────────────╖
  3808.  Machine           ADR                   ADS
  3809.  ───────────────────────────────────────────────────────────────────────────
  3810.  8080              16-bit absolute       Same as ADR
  3811.  
  3812.  8086              16-bit default        16-bit offset,
  3813.                    data segment offset   16-bit segment
  3814.  
  3815.  Z8000             16-bit data           Same as ADR
  3816.  (unsegmented)     absolute
  3817.  
  3818.  Z8000             Same as ADS           16-bit segment,
  3819.  (segmented)                             16-bit offset
  3820.  
  3821.  See your Microsoft Pascal Compiler User's Guide for details specific
  3822.  to your implementation of the compiler.
  3823.  
  3824.  In MS-Pascal, you may declare a variable that is an address:
  3825.  
  3826.       VAR  X : ADR OF BYTE;
  3827.  
  3828.  Then, with the following record notation, you can assign numeric
  3829.  values to the actual variable:
  3830.  
  3831.       X.R := 16#FFFF
  3832.  
  3833.  In an unsegmented environment, the .R (relative address) is the only
  3834.  record field available for ADR and ADS addresses.
  3835.  
  3836.  Since MS-Pascal allows nondecimal numbering, you may specify the
  3837.  assigned value in hexadecimal notation. You may also assign to a
  3838.  segment field with the ADS type in a segmented environment, using the
  3839.  field notation .S (segment address). Thus, you may declare a variable of
  3840.  an ADS type and then assign values to its two fields:
  3841.  
  3842.       VAR Y : ADS OF WORD;
  3843.         .
  3844.         .
  3845.       Y.S := 16#0001
  3846.       Y.R := 16#FFFF
  3847.  
  3848.  As shown above, any 16-bit value can be directly assigned to address
  3849.  type variables, using the .R and .S fields. The ADR and ADS operators
  3850.  obtain these addresses directly. The example below assigns addresses this
  3851.  way to the variables X and Y:
  3852.  
  3853.       VAR  X : ADR OF BYTE;
  3854.            Y : ADS OF WORD;
  3855.            W : WORD;
  3856.            B : BYTE;
  3857.              .
  3858.              .
  3859.            X := ADR B;
  3860.            Y := ADS W;
  3861.  
  3862.  MS-Pascal supports these two predeclared address types:
  3863.  
  3864.       ADRMEM = ADR OF ARRAY [0..32766] OF BYTE;
  3865.       ADSMEM = ADS OF ARRAY [0..32766] OF BYTE;
  3866.  
  3867.  Since the type referred to by the address is an array of bytes, byte
  3868.  indexing is possible. For example, if A is of type ADRMEM, then A^[15] is
  3869.  the byte at the address A.R + 15, where .R specifies an actual 16-bit
  3870.  address.
  3871.  
  3872.  You can use the address types for a constant address (a form of
  3873.  structured constant); you may also take the address of a constant or
  3874.  expression. For example:
  3875.  
  3876.       TYPE ADRWORD = ADR OF WORD;
  3877.            ADSWORD = ADS OF WORD;
  3878.       VAR W : WORD;
  3879.           R : ADRWORD;
  3880.       CONST CONADR = ADRWORD (1234);
  3881.       BEGIN
  3882.         W := CONADR^;
  3883.         {Get word at address 1234}
  3884.         W := ADSWORD (0, 32)^;
  3885.         {Get word at address 0:32}
  3886.         W := (ADS W).S;
  3887.         {Get value of DS segment register}
  3888.         R := ADR '123';
  3889.         {Get address of a constant value}
  3890.         R := ADR (W DIV 2 + 1)
  3891.         {Get address of expression value}
  3892.       END;
  3893.  
  3894.  However, constants or expressions that yield addresses cannot currently be
  3895.  used as the target of an assignment (or as a reference parameter or WITH
  3896.  record), as shown:
  3897.  
  3898.       CONST ADSCON = ADSWORD (256, 64);   {OK}
  3899.       FUNCTION SOME_ADDRESS: ADSWORD;     {OK}
  3900.       BEGIN
  3901.         ADSWORD (0, 32)^ := W; {Not permitted}
  3902.         ADSCON^ := 12; {Not permitted}
  3903.         SOME_ADDRESS^ := 100 {Not permitted}
  3904.       END;
  3905.  
  3906.  
  3907.  9.1.3  Segment Parameters for the Address Types
  3908.  
  3909.  
  3910.  Two keywords, VARS and CONSTS, are available as parameter prefixes, like
  3911.  VAR and CONST, to pass the segmented address of a variable. If P is of
  3912.  type ADS FOO, then P^ can be passed to a VARS formal parameter, such as
  3913.  VARS X : FOO, but cannot be passed to a VAR formal parameter.
  3914.  
  3915.  In a segmented machine environment, a default data segment is assumed,
  3916.  in which case a VAR parameter is passed as the default data segment offset
  3917.  of a variable. A VARS parameter is passed as both the segment value and the
  3918.  offset value.
  3919.  
  3920.  In the 8086 environment, both VARS parameters and ADS variables have
  3921.  the offset (.R) value in the WORD with the lower address and the segment
  3922.  (.S) value in the address plus two.
  3923.  
  3924.  In the segmented Z8000 environment, the segment (.S) value is in the
  3925.  lower address and the offset (.R) value in the address plus two. Also, the
  3926.  ADR type is identical to the ADS type.
  3927.  
  3928.  In the nonsegmented environment (e.g., 8080), VAR and CONST are
  3929.  identical to VARS and CONSTS. Since ADS and ADR are identical in a
  3930.  nonsegmented environment, the ADS type is useful in situations where the
  3931.  target environment may change. For example, in MS-Pascal, some primitive
  3932.  file system calls are declared with ADS parameters.
  3933.  
  3934.  In pointer type declarations, the up arrow (^) prefixes the type
  3935.  pointed to; in program statements, it dereferences a pointer so that the
  3936.  value pointed to can be assigned or operated on. The up arrow also
  3937.  dereferences ADR and ADS types in program statements.
  3938.  
  3939.  Component selection with the up arrow (^) is performed before the
  3940.  unary operators ADR or ADS. Because the up arrow (^) selector can appear
  3941.  after any address variable to produce a new variable, it can occur, for
  3942.  example, in the target of an assignment, a reference parameter, as well as
  3943.  in expressions. Since ADS and ADR are prefix operators, they are used only
  3944.  in expressions, where they apply only to a variable or constant or
  3945.  expression.
  3946.  
  3947.  Pascal is a strongly typed language; two pointer variables are
  3948.  compatible only if they have the same type (it is not enough that they
  3949.  point to the same type). However, two address types are considered the
  3950.  same type if they are both ADR or both ADS types. This lets you assign an
  3951.  ADR OF WORD to an ADR OF STRING (200). Such an assignment would make it
  3952.  easy to wipe out part of memory by assigning a variable of type
  3953.  STRING (200) to the 200 bytes starting at the address of a WORD variable.
  3954.  
  3955.  If P1 is type ADR OF STRING (200) and P2 is any ADR OF type, the
  3956.  assignment P1^ := P2^ generates fast code with no range checking. Although
  3957.  this capability is not safe, operating systems and other software sometimes
  3958.  require it.
  3959.  
  3960.  ADR and ADS are not compatible with each other, but the .R notation
  3961.  should overcome or reduce the problem.
  3962.  
  3963.  
  3964.  9.1.4  Using the Address Types
  3965.  
  3966.  
  3967.  Within limits, you may combine and intermingle the two address types.
  3968.  The following example illustrates the rules that apply in a segmented
  3969.  environment:
  3970.  
  3971.       VAR
  3972.         P : ADS OF DATA;
  3973.         {P is segmented address of type DATA.}
  3974.         Q : ADR OF DATA;
  3975.         {Q is relative address of type DATA.}
  3976.         X : DATA;
  3977.         {X is some variable of type DATA.}
  3978.  
  3979.       BEGIN
  3980.         P := ADS X;
  3981.         {Assign the address of X to P.}
  3982.         X := P^;
  3983.         {Assign to X the value pointed to by P.}
  3984.         P := ADS P^;
  3985.         {Assign to P the address of the value whose}
  3986.         {address is pointed to by P. P is unchanged}
  3987.         {by this assignment.}
  3988.         Q := ADR X;
  3989.         {Assign the relative address of X to Q.}
  3990.         Q.R  := (ADR X).R;
  3991.         {Assign the relative address of X to Q,}
  3992.         {using the WORD type.}
  3993.         P := ADS Q^;
  3994.         {Assign the address of the variable at Q to P.}
  3995.         {You can always apply ADS to ADR^.}
  3996.         Q := ADR P^;
  3997.         {Illegal; you cannot apply ADR to ADS^.}
  3998.         P.R := 16#8000;
  3999.         {Assign 32768 to P's offset field.}
  4000.         P.S := 16;
  4001.         {Assign 16 to P's segment field.}
  4002.         Q.R := P.R + 4
  4003.         {Assign P's offset plus 4 to be the value of Q.}
  4004.       END;
  4005.  
  4006.  See also the examples given in Section 9.1.2, "Address Types."
  4007.  
  4008.  
  4009.  9.1.5  Notes on Reference Types
  4010.  
  4011.  
  4012.  The address type and pointer type should be treated as two distinct types.
  4013.  The pointer type, in theory, is just an undefined mapping from one variable
  4014.  to another variable. The method of implementation is undefined. However,
  4015.  the address type deals with actual machine addresses.
  4016.  
  4017.  Therefore, the pointer type is an abstract data type that works the
  4018.  same in all implementations; the address type is generally not portable,
  4019.  unless used with some caution. Address types are portable only if you
  4020.  restrict yourself to using ADS and never assign to fields. Even with these
  4021.  restrictions, however, they can be quite useful.
  4022.  
  4023.  The following special facilities that use pointer variables are not
  4024.  allowed with address variables.
  4025.  
  4026.      1.  The NEW and DISPOSE procedures are only permitted with pointers.
  4027.          NIL does not apply to the address type. There are no special
  4028.          address values for empty, uninitialized, or invalid addresses.
  4029.  
  4030.      2.  The type "address of super array type" is not supported in the same
  4031.          way as "pointer to super array type." Getting the address of a
  4032.          super array variable is still permitted with ADR and ADS. For
  4033.          example, if a procedure or function formal parameter is declared as
  4034.          VAR S : STRING, then within the procedure or function, the
  4035.          expression ADS S is fine. Unlike a pointer, the address does not
  4036.          contain any upper bounds.
  4037.  
  4038.  
  4039.  9.2  PACKED Types
  4040.  
  4041.  
  4042.  Any of the structured types can be PACKED. This could economize storage
  4043.  at the possible expense of access time or access code space. However,
  4044.  in MS-Pascal, some limitations on the use of PACKED structures currently
  4045.  apply:
  4046.  
  4047.      1.  The prefix PACKED is always ignored, except for type checking, in
  4048.          sets, files, and arrays of characters. In most versions of MS-
  4049.          Pascal it has no actual effect on the representation of records and
  4050.         other arrays. Furthermore, PACKED can only precede one of the
  4051.          structure names ARRAY, RECORD, SET, or FILE; it cannot precede a
  4052.          type identifier. For example, if COLORMAP is the identifier for an
  4053.          unpacked array type, "PACKED COLORMAP" is not accepted.
  4054.  
  4055.      2.  A component of a PACKED structure cannot be passed as a reference
  4056.          parameter or used as the record of a WITH statement, unless the
  4057.          structure is of a string type. Also, obtaining the address of a
  4058.          PACKED component with ADR or ADS is not permitted.
  4059.  
  4060.      3.  A PACKED prefix only applies to the structure being defined:  any
  4061.          components of that structure that are also structures are not
  4062.          packed unless you explicitly include the reserved word PACKED in
  4063.          their definition. The only exception to this rule, n-dimensional
  4064.          arrays, is discussed in Section 7.1, "Arrays."
  4065.  
  4066.  
  4067.  9.3  Procedural and Functional Types
  4068.  
  4069.  
  4070.  Procedural and functional types are different from other MS-Pascal
  4071.  types. (Wherever the term "procedural" is used from here on, both
  4072.  procedural and functional is implied.) You may not declare an identifier
  4073.  for a procedural type in a TYPE section; nor may you declare a variable of
  4074.  a procedural type. However, you may use procedural types to declare the
  4075.  type of a procedural parameter, and in this sense they conform to the
  4076.  Pascal idea of a type.
  4077.  
  4078.  A procedural type defines a procedure or function heading and gives
  4079.  any parameters. For a function, it also defines the result type. The
  4080.  syntax of a procedural type is the same as a procedure or function heading,
  4081.  including any attributes. There are no procedural variables in MS-Pascal,
  4082.  only procedural parameters.
  4083.  
  4084.  Example of a procedural type declaration:
  4085.  
  4086.       PROCEDURE ZERO (FUNCTION FUN (X, Y : REAL) : REAL)
  4087.  
  4088.  The parameter identifiers in a procedural type (X and Y in the
  4089.  previous example) are ignored; only their type is important.
  4090.  
  4091.  See Section 14.4.3, "Procedural and Functional Parameters," for more
  4092.  information about procedural types in MS-Pascal.
  4093.  
  4094.  
  4095.  
  4096.  Chapter 10  Constants
  4097.  
  4098.  ───────────────────────────────────────────────────────────────────────────
  4099.  
  4100.  10.1  What Is a Constant?
  4101.  
  4102.  10.2  Declaring Constant Identifiers
  4103.  
  4104.  10.3  Numeric Constants
  4105.  
  4106.         10.3.1  REAL Constants
  4107.  
  4108.         10.3.2  INTEGER, WORD, and INTEGER4 Constants
  4109.  
  4110.         10.3.3  Nondecimal Numbering
  4111.  
  4112.  10.4  Character Strings
  4113.  
  4114.  10.5  Structured Constants
  4115.  
  4116.  10.6  Constant Expressions
  4117.  
  4118.  
  4119.  
  4120.  10.1  What Is a Constant?
  4121.  
  4122.  
  4123.  A constant is a value that is known before a program starts and that will
  4124.  not change as the program progresses. Examples of constants include the
  4125.  number of days in the week, your birthdate, the name of your dog, or the
  4126.  phases of the moon.
  4127.  
  4128.  A constant may be given an identifier, but you cannot alter the value
  4129.  associated with that identifier during the execution of the program. When
  4130.  you declare a constant, its identifier becomes a synonym for the constant
  4131.  itself.
  4132.  
  4133.  Each constant implicitly belongs to some category of data:
  4134.  
  4135.      1.  Numeric constants (discussed in Section 10.3, "Numeric Constants")
  4136.          are one of the several number types: REAL, INTEGER, WORD, or
  4137.          INTEGER4.
  4138.  
  4139.      2.  Character constants (discussed in Section 10.4, "Character
  4140.          Strings") are strings of characters enclosed in single quotation
  4141.          marks and are called "string literals" in Microsoft Pascal.
  4142.  
  4143.      3.  Available at the extend level, structured constants (discussed in
  4144.          Section 10.5, "Structured Constants") include constant arrays,
  4145.          records, and typed sets.
  4146.  
  4147.  Also available at the extend level, constant expressions (discussed in
  4148.  Section 10.6, "Constant Expressions") let you compute a constant based on
  4149.  the values of previously declared constants in expressions.
  4150.  
  4151.  The identifiers defined in an enumerated type are constants of that
  4152.  type and cannot be used directly with numeric (or string) constant
  4153.  expressions. These identifiers can be used with the ORD, WRD, or CHR
  4154.  functions (e.g., ORD (BLUE)). The extend level also permits directly
  4155.  reading and writing the enumerated type's constant identifiers as
  4156.  character strings.
  4157.  
  4158.  TRUE and FALSE are predeclared constants of type BOOLEAN and can be
  4159.  redeclared. NIL is a constant of any pointer type; however, because it is
  4160.  a reserved word, you may not redefine it. Also, the null set is a constant
  4161.  of any set type.
  4162.  
  4163.  Numeric statement labels have nothing to do with numeric constants;
  4164.  you may not use a constant identifier or expression as a label.
  4165.  Internally,  all constants are limited in length to a maximum of 255
  4166.  bytes.
  4167.  
  4168.  
  4169.  10.2  Declaring Constant Identifiers
  4170.  
  4171.  
  4172.  Declaring a constant identifier introduces the identifier as a synonym
  4173.  for the constant. You put these declarations in the CONST section of a
  4174.  compiland, procedure, or function.
  4175.  
  4176.  The general form of a constant identifier declaration is the identifier
  4177.  followed by an equal sign and the constant value. The following program
  4178.  fragment includes three statements that identify constants (beginning
  4179.  after the word "CONST"):
  4180.  
  4181.       PROGRAM DEMO (INPUT, OUTPUT);
  4182.       CONST DAYS_IN_YEAR = 365;
  4183.             DAYS_IN_WEEK = 7;
  4184.             NAME_OF_PLANET = 'EARTH';
  4185.  
  4186.  In this example, the numbers 365 and 7 are numeric constants; must be
  4187.  enclosed in single quotation marks.
  4188.  
  4189.  When you compile a program, the constant identifiers are not actually
  4190.  defined until after the declarations are processed. Thus, a constant
  4191.  declaration like the following has no meaning:
  4192.  
  4193.       N = -N
  4194.  
  4195.  The ISO standard defines a strict order in which to set out the
  4196.  declarations in the declaration section of a program:
  4197.  
  4198.       CONST MAX = 10;
  4199.       TYPE NAME = PACKED ARRAY [1..MAX] OF CHAR;
  4200.       VAR FIRST : NAME;
  4201.  
  4202.  MS-Pascal relaxes this order and, in fact, allows more than one instance of
  4203.  each kind of declaration:
  4204.  
  4205.       TYPE COMPLEX = RECORD R, I : REAL END;
  4206.       CONST PII = COMPLEX (3.1416, 00);
  4207.       VAR PIX : COMPLEX;
  4208.       TYPE IVEC = ARRAY [1..3] OF COMPLEX;
  4209.       CONST PIVEC = IVEC (PII, PII, COMPLEX (0.0, 1.0));
  4210.  
  4211.  
  4212.  10.3  Numeric Constants
  4213.  
  4214.  
  4215.  Numeric constants are irreducible numbers such as 45, 12.3, and 9E12.
  4216.  The notation of a numeric constant generally indicates its type: REAL,
  4217.  INTEGER, WORD, or INTEGER4.
  4218.  
  4219.  Numbers can have a leading plus sign (+) or minus sign (-), except
  4220.  when the numbers are within expressions. Therefore:
  4221.  
  4222.       ALPHA := +10       {Is legal}
  4223.       ALPHA + -10        {Is illegal}
  4224.  
  4225.  Blanks embedded within constants are not permitted.
  4226.  
  4227.  The compiler truncates any number that exceeds a certain maximum
  4228.  number of characters and gives a warning when this occurs. The maximum
  4229.  length of constants (either 19 or 31) is the same as the maximum length of
  4230.  identifiers. For the maximum length of constants and identifiers in a
  4231.  particular version of the language, see Appendix B "Version Specifics," in
  4232.  your Microsoft Pascal Compiler User's Guide.
  4233.  
  4234.  The syntax for numeric constants applies not only to the actual text
  4235.  of programs, but also to the content of textfiles read by a program.
  4236.  
  4237.  Examples of numeric constants:
  4238.  
  4239.        123                0.17
  4240.       +12.345             007
  4241.       -1.7E-10           -26.0
  4242.        17E+3              26.0E12
  4243.       -17E3               1E1
  4244.  
  4245.  Numeric constants can appear in any of the following:
  4246.  
  4247.      1.  CONST sections
  4248.  
  4249.      2.  expressions
  4250.  
  4251.      3.  type clauses
  4252.  
  4253.      4.  set constants
  4254.  
  4255.      5.  structured constants
  4256.  
  4257.      6.  CASE statement CASE constants
  4258.  
  4259.      7.  variant record tag values
  4260.  
  4261.  The different types of numeric constants are discussed in detail in the
  4262.  following sections.
  4263.  
  4264.  
  4265.  10.3.1  REAL Constants
  4266.  
  4267.  
  4268.  The type of a number is REAL if the number includes a decimal point or
  4269.  exponent. The REAL value range depends on the REAL number unit of the
  4270.  target machine. Generally, either the IEEE or the Microsoft REAL number
  4271.  format is used. This provides about seven digits of precision, with a
  4272.  maximum value of about 1.701411E38.
  4273.  
  4274.  There is, however, a distinction between REAL values and REAL constants.
  4275.  The REAL constant range may be a subset of the REAL value range. In
  4276.  Microsoft format, REAL numeric constants must be greater than or equal
  4277.  to 1.0E-38 and less than 1.0E+38. In IEEE format, REAL numeric constants
  4278.  are kept in double precision and so can range from about 1E-306 to 1E+306.
  4279.  
  4280.  The compiler issues a warning if there is not at least one digit on
  4281.  each side of a decimal point. A REAL number starting or ending with a
  4282.  decimal point may be misleading. For example, because left parenthesis-
  4283.  period substitutes for left square bracket, and right parenthesis-period
  4284.  for right square bracket, the following:
  4285.  
  4286.       (.1 + 2.)
  4287.  
  4288.  is interpreted as:
  4289.  
  4290.       [1 + 2]
  4291.  
  4292.  Scientific notation in REAL numbers (as in 1.23E-6 or 4E7) is supported.
  4293.  The decimal point and exponent sign are optional when an exponent is given.
  4294.  Both the uppercase "E" and the lowercase "e" are allowed in REAL numbers.
  4295.  "D" and "d" are also allowed to indicate an exponent. This provides
  4296.  compatibility with other languages.
  4297.  
  4298.  When IEEE REAL4 and REAL8 format are used, all real constants are
  4299.  stored in REAL8 (double precision) format. If you require a single
  4300.  precision REAL4 constant, declare a REAL4 variable and give it your real
  4301.  constant value in a VALUE section. (You may wish to give this variable the
  4302.  READONLY attribute as well.)
  4303.  
  4304.  Versions of the compiler that run on one machine but generate code for
  4305.  another may lose a small amount of significance in REAL constants.
  4306.  
  4307.  
  4308.  10.3.2  INTEGER, WORD, and INTEGER4 Constants
  4309.  
  4310.  
  4311.  The type of a non-REAL numeric constant is INTEGER, WORD, or INTEGER4.
  4312.  Table 10.1 shows the range of values that constants of each of these types
  4313.  can assume.
  4314.  
  4315.  
  4316.  Table 10.1.
  4317.  INTEGER, WORD, and INTEGER4 Constants
  4318. ╓┌────────────┌───────────────────────┌──────────────────────────────────────╖
  4319.  Type         Range of Values         Predeclared
  4320.               (minimum/maximum)       Constant
  4321.  ───────────────────────────────────────────────────────────────────────────
  4322.  INTEGER      -MAXINT to MAXINT       MAXINT=32767
  4323.  
  4324.  WORD          0 to MAXWORD           MAXWORD=65535
  4325.  
  4326.  INTEGER4     -MAXINT4 to MAXINT4     MAXINT4=2147483647
  4327.  
  4328.  MAXINT, MAXWORD, and MAXINT4 are all predeclared constant identifiers.
  4329.  
  4330.  One of three things happens when you declare a numeric constant
  4331.  identifier:
  4332.  
  4333.      1.  A constant identifier from -MAXINT to MAXINT becomes an INTEGER.
  4334.  
  4335.      2.  A constant identifier from MAXINT+1 to MAXWORD becomes a WORD.
  4336.  
  4337.      3.  A constant identifier from -MAXINT4 to -MAXINT-1 or MAXWORD+1 to
  4338.          MAXINT4 becomes an INTEGER4.
  4339.  
  4340.  However, any INTEGER type constant (including constant expressions and
  4341.  values from -32767 to -1) automatically changes to type WORD; if the
  4342.  INTEGER value is negative, 65536 is added to it and the underlying 16-bit
  4343.  value is not changed.
  4344.  
  4345.  For example, you can declare a subrange of type WORD as WRD(0)..127;
  4346.  the upper bound of 127 is automatically given the type WORD. The reverse
  4347.  is not true; constants of type WORD are not automatically changed to type
  4348.  INTEGER.
  4349.  
  4350.  The ORD and WRD functions also change the type of an ordinal constant
  4351.  to INTEGER or WORD. Also, any INTEGER or WORD constant automatically
  4352.  changes to type INTEGER4 if necessary, but the reverse is not true.
  4353.  
  4354.  Examples of relevant conversions are given in Table 10.2.
  4355.  
  4356.  
  4357.  Table 10.2
  4358.  Constant Conversions
  4359. ╓┌─────────────────┌─────────────────────────────────────────────────────────╖
  4360.  Constant          Assumed Type
  4361.  ───────────────────────────────────────────────────────────────────────────
  4362.          0         INTEGER could become WORD or INTEGER4
  4363.  
  4364.     -32768         INTEGER4 only
  4365.  
  4366.      32768         WORD could become INTEGER4
  4367.  
  4368.   0..20000         INTEGER subrange
  4369.  
  4370.  Constant          Assumed Type
  4371. 
  4372.   0..50000         WORD subrange
  4373.  
  4374.   0..80000         Invalid: no INTEGER4 subranges
  4375.  
  4376.  -1..50000         Invalid: becomes 65535..50000
  4377.                    (i.e., -1 is treated as 65536)
  4378.  
  4379.  At the standard level, any numeric constant (i.e., literal or identifier)
  4380.  may have a plus (+) or minus (-) sign.
  4381.  
  4382.  
  4383.  10.3.3  Nondecimal Numbering
  4384.  
  4385.  
  4386.  At the extend level, MS-Pascal supports not only decimal number notation,
  4387.  but also numbers in hexadecimal, octal, binary, or other base numbering
  4388.  (where the base can range from 2 to 36). The number sign (#) acts as a
  4389.  radix separator.
  4390.  
  4391.  Examples of numbers in nondecimal notation:
  4392.  
  4393.       16#FF02
  4394.       10#987
  4395.        8#776
  4396.        2#111100
  4397.  
  4398.  Leading zeros are recognized in the radix, so a number like 008#147 is
  4399.  permitted. In hexadecimal notation, upper or lowercase letters A through F
  4400.  are permitted. A nondecimal constant without the radix (such as #44) is
  4401.  assumed to be hexadecimal. Nondecimal notation does not imply a WORD
  4402.  constant and may be used for INTEGER, WORD, or INTEGER4 constants. You
  4403.  must not use nondecimal notation for REAL constants or numeric statement
  4404.  labels.
  4405.  
  4406.  
  4407.  10.4  Character Strings
  4408.  
  4409.  
  4410.  Most Pascal manuals refer to sequences of characters enclosed in single
  4411.  quotation marks as "strings." In MS-Pascal, they are called "string
  4412.  literals" to distinguish them from string constants, which may be
  4413.  expressions, or values of the STRING type.
  4414.  
  4415.  A string constant contains from 1 to 255 characters. A string
  4416.  constant longer than one character is of type PACKED ARRAY [1..n] OF
  4417.  CHAR, also known in MS-Pascal as the type STRING (n). A string constant
  4418.  that contains just one character is of type CHAR. However, the type
  4419.  changes from CHAR to PACKED ARRAY [1..1] OF CHAR (e.g., STRING (1)) if
  4420.  necessary. For example, a constant ('A') of type CHAR could be assigned to
  4421.  a variable of type STRING (1).
  4422.  
  4423.  A literal apostrophe (single quotation mark) is represented by two
  4424.  adjacent single quotation marks (e.g., 'DON''T GO'). The null string ('')
  4425.  is not permitted. A string literal must fit on a line. The compiler
  4426.  recognizes string literals enclosed in double quotations marks (" ") or
  4427.  accent marks (─), instead of single quotation marks, but issues a warning
  4428.  message when it encounters them.
  4429.  
  4430.  The constant expression feature (discussed in Section 10.6, "Constant
  4431.  Expressions") permits string constants made up of concatenations of
  4432.  other string constants, including string constant identifiers, the CHR ()
  4433.  function, and structured constants of type STRING. This is useful for
  4434.  representing string constants that are longer than a line or that contain
  4435.  nonprinting characters. For example:
  4436.  
  4437.     'THIS IS UNDERLINED' * CHR(13) * STRING (DO 18 OF '_')
  4438.  
  4439.  The LSTRING feature of MS-Pascal adds the super array type LSTRING.
  4440.  LSTRING is similar to PACKED ARRAY [0..n] OF CHAR, except that element 0
  4441.  contains the length of the string, which can vary from 0 to a maximum of
  4442.  255. (See Section 7.2.2, "LSTRINGs," for a discussion of LSTRINGs.) For
  4443.  now, note that, if necessary, a constant of type STRING (n) or CHAR changes
  4444.  automatically to type LSTRING.
  4445.  
  4446.  NULL is a predeclared constant for the null LSTRING, with the element
  4447.  0 (the only element) equal to CHR (0). NULL cannot be concatenated, since
  4448.  it is not of type STRING. It is the only constant of type LSTRING.
  4449.  
  4450.  Examples of string literal declarations:
  4451.  
  4452.       NAME = 'John Jacob';    {a legal string literal}
  4453.       LETTER = 'Z';           {LETTER is of type CHAR}
  4454.       QUOTED_QUOTE = '''';    {Quotes quote}
  4455.       NULL_STRING = NULL;     {legal}
  4456.       NULL_STRING = '';       {illegal}
  4457.       DOUBLE = "OK";          {generates a warning}
  4458.  
  4459.  
  4460.  10.5  Structured Constants
  4461.  
  4462.  
  4463.  Standard Pascal permits only the numeric and string constants already
  4464.  mentioned, the pointer constant value NIL, and untyped constant sets.
  4465.  
  4466.  At the extend level of MS-Pascal, however, you may use constant
  4467.  arrays, records, and typed sets. Structured constants can be used
  4468.  anywhere a structured value is allowed, in expressions as well as
  4469.  in CONST and VALUE sections.
  4470.  
  4471.   1.  An array constant consists of a type identifier followed by a
  4472.       list of constant values in parentheses separated by commas.
  4473.  
  4474.       Example of an array constant:
  4475.  
  4476.          TYPE VECT_TYPE = ARRAY [-2..2] OF INTEGER;
  4477.          CONST VECT = VECT_TYPE (5, 4, 3, 2, 1);
  4478.          VAR A : VECT_TYPE;
  4479.          VALUE A := VECT;
  4480.  
  4481.   2.  A record constant consists of a type identifier followed by a list of
  4482.       constant values in parentheses separated by commas.
  4483.  
  4484.       Example of a record constant:
  4485.  
  4486.          TYPE REC_TYPE = RECORD
  4487.                 A, B : BYTE;
  4488.                 C, D : CHAR
  4489.               END;
  4490.          CONST RECR = REC_TYPE ( 20, 0, 'A', CHR (20));
  4491.          VAR FOO : REC_TYPE;
  4492.          VALUE FOO := RECR;
  4493.  
  4494.   3.  A set constant consists of an optional set type identifier followed by
  4495.       set constant elements in square brackets. Set constant elements are
  4496.       separated by commas. A set constant element is either an ordinal
  4497.       constant, or two ordinal constants separated by two dots to indicate a
  4498.       range of constant values.
  4499.  
  4500.       Example of a set constant:
  4501.  
  4502.          TYPE COLOR_TYPE = SET OF
  4503.             (RED, BLUE, WHITE, GREY, GOLD);
  4504.          CONST SETC = COLOR_TYPE [RED, WHITE .. GOLD];
  4505.          VAR RAINBOW : COLOR_TYPE;
  4506.          VALUE RAINBOW := SETC;
  4507.  
  4508.  A constant within a structured array or record constant must have a type
  4509.  that can be assigned to the corresponding component type. For records with
  4510.  variants, the value of a constant element corresponding to a tag field
  4511.  selects a variant, even if the tag field is empty. The number of constant
  4512.  elements must equal the number of components in the structure, except for
  4513.  super array type structured constants. Nested structured constants are
  4514.  permitted.
  4515.  
  4516.  An array or record constant nested within another structured constant
  4517.  must still have the preceding type identifier. For this reason, a
  4518.  super array constant can have only one dimension (see Section 7.2, "Super
  4519.  Arrays," for a discussion of super arrays). The size of the representation
  4520.  of a structured constant must be from 1 to 255 bytes. If this 255-byte
  4521.  limit is a problem, declare a structured variable with the READONLY
  4522.  attribute, and initialize its components in a VALUE section.
  4523.  
  4524.  Example of a complex structured constant:
  4525.  
  4526.       TYPE R3 = ARRAY [1..3] OF REAL;
  4527.       TYPE SAMPLE = RECORD I : INTEGER;
  4528.                            A : R3;
  4529.                            CASE BOOLEAN OF
  4530.                            TRUE : (S : SET OF 'A'..'Z';
  4531.                                    P : ^SAMPLE);
  4532.                            FALSE : (X : INTEGER)
  4533.                        END;
  4534.       CONST SAMP_CONST = SAMPLE (27, R3 (1.4, 1.4, 1.4),
  4535.                         TRUE, ['A','E','I'], NIL);
  4536.  
  4537.  Constant elements can be repeated with the phrase DO n OF constant, so
  4538.  the previous example could have included "DO 3 OF 1.4" instead of "1.4,
  4539.  1.4, 1.4".
  4540.  
  4541.  MS-Pascal does not support set constant expressions, such as
  4542.  ['_'] + LETTERS, or file constant expressions. The  constant 'ABC' of type
  4543.  STRING (3) is equivalent to the structured constant STRING ('A', 'B', 'C').
  4544.  LSTRING structured constants are not permitted; use the corresponding
  4545.  STRING constants instead.
  4546.  
  4547.  Structured constants (and other structured values, such as variables
  4548.  and values returned from functions) can be passed by reference using CONST
  4549.  parameters. For more information, see Section 14.4, "Procedure and Function
  4550.  Parameters."
  4551.  
  4552.  There are two kinds of set constants: one with an explicit type, as in
  4553.  CHARSET ['A'..'Z'], and one with an unknown type, as in [20..40]. You may
  4554.  use either in an expression or to define the value of a constant
  4555.  identifier. Set constants with an explicit type may also be passed as a
  4556.  reference (CONST) parameter. Sets of unknown type are unpacked, but the
  4557.  type changes to PACKED if necessary. Passing sets by reference is
  4558.  generally more efficient than passing them as value parameters.
  4559.  
  4560.  
  4561.  10.6  Constant Expressions
  4562.  
  4563.  
  4564.  Constant expressions in MS-Pascal allow you to compute constants based
  4565.  on the values of previously declared constants in expressions. Constant
  4566.  expressions can also occur within program statements.
  4567.  
  4568.  Example of a constant expression declaration:
  4569.  
  4570.       CONST HEIGHT_OF_LADDER = 6;
  4571.             HEIGHT_OF_MAN = 6;
  4572.             REACH = HEIGHT_OF_LADDER + HEIGHT_OF_MAN;
  4573.  
  4574.  Because a constant expression may contain only constants that you have
  4575.  declared earlier, the following is illegal:
  4576.  
  4577.       CONST MAX = A + B;
  4578.             A = 10;
  4579.             B = 20;
  4580.  
  4581.  Certain functions may be used within constant expressions. For
  4582.  example:
  4583.  
  4584.       CONST A = LOBYTE (-23) DIV 23;
  4585.             B = HIBYTE (-A);
  4586.  
  4587.  Table 10.3 shows the functions and operators you may use with REAL,
  4588.  INTEGER, WORD, and other ordinal constants, such as enumerated and
  4589.  subrange constants.
  4590.  
  4591.  
  4592.  Table 10.3.
  4593.  Constant Operators and Functions
  4594. ╓┌──────────────────────────────┌────────────────────────────────────────────╖
  4595.  Type of Operand                Functions and Operators
  4596.  ───────────────────────────────────────────────────────────────────────────
  4597.  REAL, INTEGER                  Unary plus  (+)
  4598.                                 Unary minus (-)
  4599.  
  4600.  INTEGER, WORD                  +   DIV  OR    HIBYTE()
  4601.  Type of Operand                Functions and Operators
  4602. INTEGER, WORD                  +   DIV  OR    HIBYTE()
  4603.                                 -   MOD  NOT   LOBYTE()
  4604.                                 *   AND  XOR   BYWORD()
  4605.  
  4606.  Ordinal types                  <   <=   CHR()   LOWER()
  4607.                                 >   >=   ORD()   UPPER()
  4608.                                 =   <>   WRD()
  4609.  
  4610.  Boolean                        AND     NOT     OR
  4611.  
  4612.  ARRAY                          LOWER()     UPPER()
  4613.  
  4614.  Any type                       SIZEOF()    RETYPE()
  4615.  
  4616.  Examples of constant expressions:
  4617.  
  4618.       CONST FOO = (100 + ORD('X')) * 8#100 + ORD('Y');
  4619.             MAXSIZE = 80;
  4620.             X = (MAXSIZE > 80) OR (IN_TYPE = PAPERTAPE);
  4621.             {X is a BOOLEAN constant}
  4622.  
  4623.  In addition to the operators shown in Table 10.3 for numeric
  4624.  constants, you may use the string concatenation operator (*) with string
  4625.  constants, as follows:
  4626.  
  4627.       CONST A = 'abcdef';
  4628.             M = CHR (109); {CHR is allowed}
  4629.             A_TO_M = A * 'ghijkl' * M;
  4630.             {A_TO_M = 'abcdefghijklm'}
  4631.  
  4632.  These constants can span more than one line, but are still limited to the
  4633.  255 character maximum. These string constant expressions are allowed
  4634.  wherever a string literal is allowed, except in metacommands.
  4635.  
  4636.  
  4637.  Chapter 11  Variables and Values
  4638.  
  4639.  ───────────────────────────────────────────────────────────────────────────
  4640.  
  4641.  11.1  What Is a Variable?
  4642.  
  4643.  11.2  Declaring a Variable
  4644.  
  4645.  11.3  The VALUE Section
  4646.  
  4647.  11.4  Using Variables and Values
  4648.  
  4649.         11.4.1  Components of Entire Variables and Values
  4650.  
  4651.                  11.4.1.1  Indexed Variables and Values
  4652.  
  4653.                  11.4.1.2  Field Variables and Values
  4654.  
  4655.                  11.4.1.3  File Buffers and Fields
  4656.  
  4657.         11.4.2  Reference Variables
  4658.  
  4659.  11.5  Attributes
  4660.  
  4661.         11.5.1  The STATIC Attribute
  4662.  
  4663.         11.5.2  The PUBLIC and EXTERN Attributes
  4664.  
  4665.         11.5.3  The ORIGIN and PORT Attributes
  4666.  
  4667.         11.5.4  The READONLY Attribute
  4668.  
  4669.         11.5.5  Combining Attributes
  4670.  
  4671.  
  4672.  
  4673.  This chapter describes Microsoft Pascal variable types and the ways
  4674.  you can set their values and attributes.
  4675.  
  4676.  
  4677.  11.1  What Is a Variable?
  4678.  
  4679.  
  4680.  A variable is a value that is expected to change during the course of a
  4681.  program. Every variable must be of a specific data type. A variable may
  4682.  have an identifier.
  4683.  
  4684.  If A is a variable of type INTEGER, then the use of A in a program
  4685.  actually refers to the data denoted by A. For example:
  4686.  
  4687.       VAR A : INTEGER;
  4688.            BEGIN
  4689.               A := 1;
  4690.               A := A + 1
  4691.            END;
  4692.  
  4693.  These statements would first assign a value of 1 to the data denoted by A,
  4694.  and subsequently assign it a value of 2.
  4695.  
  4696.  Variables are manipulated by using some sort of notation to denote the
  4697.  variable, in the simplest case, a variable identifier. In other cases,
  4698.  variables may be denoted by array indices or record fields or the
  4699.  dereferencing of pointer or address variables.
  4700.  
  4701.  The compiler itself may sometimes create "hidden" variables, allocated
  4702.  on the stack, in circumstances like the following:
  4703.  
  4704.      1.  When you call a function that will return a structured result, the
  4705.          compiler allocates a variable in the caller for the result.
  4706.  
  4707.      2.  When you need the address of an expression (e.g., to pass it as a
  4708.          reference parameter or to use it as a WITH statement record or with
  4709.          ADR or ADS), the compiler allocates a variable for the value of the
  4710.          expression.
  4711.  
  4712.      3.  The initial and final values of a FOR loop may require allocating a
  4713.          variable.
  4714.  
  4715.      4.  When the compiler evaluates an expression, it may allocate a
  4716.          variable to store intermediate results.
  4717.  
  4718.      5.  Every WITH statement requires a variable to be allocated for the
  4719.          address of the WITH's record.
  4720.  
  4721.  
  4722.  11.2  Declaring a Variable
  4723.  
  4724.  
  4725.  A variable declaration consists of the identifier for the new variable,
  4726.  followed by a colon and a type.  You may declare variables of the same type
  4727.  by giving a list of the variable identifiers, followed by their common
  4728.  type.  For example:
  4729.  
  4730.       VAR X_COORD, Y_COORD : REAL
  4731.  
  4732.  You may declare a variable in any of the following locations:
  4733.  
  4734.  
  4735.      1.  the VAR section of a program, procedure, function, module,
  4736.          interface, or implementation
  4737.  
  4738.      2.  the formal parameter list of a procedure, function, or procedural
  4739.          parameter
  4740.  
  4741.  In a VAR section, you may declare a variable to be of any legal
  4742.  type; in a formal parameter list, you may include only a type identifier
  4743.  (i.e., you may not declare a type in the heading of a procedure or
  4744.  function).  For example:
  4745.  
  4746.       PROCEDURE NAME (GEORGE : ARRAY [1..10] OF COLOR)
  4747.       {Illegal; GEORGE is of a new type.}
  4748.  
  4749.       VAR VECTOR_A :  VECTOR (10)
  4750.       {Legal; VECTOR (10) is a type derived from}
  4751.       {a super type.}
  4752.  
  4753.  Each declaration of a file variable F of type FILE OF T implies the
  4754.  declaration of a buffer variable of type T, denoted by F^. At the
  4755.  extend level, a file declaration also implies the declaration of a record
  4756.  variable of type FCBFQQ, whose fields are denoted as F.TRAP, F.ERRS,
  4757.  F.MODE, and so on. See Section 8.2, "The Buffer Variable," and Section
  4758.  8.6, "File I/O:  Extend Level," for further information on buffer variables
  4759.  and FCBFQQ fields, respectively.
  4760.  
  4761.  
  4762.  11.3  The VALUE Section
  4763.  
  4764.  
  4765.  The VALUE section in Microsoft Pascal lets you give initial values to
  4766.  variables in a program, module, procedure, or function. You may also
  4767.  initialize the variable in an implementation, but not in an interface.
  4768.  
  4769.  The VALUE section may include only statically allocated variables,
  4770.  that is, any variable declared at the program, module, or implementation
  4771.  level, or a variable with the STATIC or PUBLIC attribute. Variables with
  4772.  the EXTERN or ORIGIN attribute cannot occur in a VALUE section, since they
  4773.  are not allocated by the compiler.
  4774.  
  4775.  The VALUE section may contain assignments of constants to entire
  4776.  variables or to components of variables. For example:
  4777.  
  4778.       VAR ALPHA : REAL;
  4779.           ID : STRING (7);
  4780.           I : INTEGER;
  4781.  
  4782.       VALUE ALPHA := 2.23;
  4783.          ID[1] := 'J';
  4784.          I := 1;
  4785.  
  4786.  However, within a VALUE section, you may not assign a variable to another
  4787.  variable. The last line in the following example is illegal, since "I" must
  4788.  be a constant:
  4789.  
  4790.       CONST MAX = 10;
  4791.       VAR I, J : INTEGER;
  4792.       VALUE I := MAX;
  4793.             J := I;
  4794.  
  4795.  If the $rom metacommand is off, variables are initialized by loading the
  4796.  static data segment. If the $rom metacommand is on, the VALUE section
  4797.  generates an error message since ROM-based systems usually cannot
  4798.  statically initialize data.
  4799.  
  4800.  
  4801.  11.4  Using Variables and Values
  4802.  
  4803.  
  4804.  At the standard level of MS-Pascal, denotation of a variable may designate
  4805.  one of three things:
  4806.  
  4807.      1.  an entire variable
  4808.  
  4809.      2.  a component of a variable
  4810.  
  4811.      3.  a variable referenced by a pointer
  4812.  
  4813.  A value may be any of the following:
  4814.  
  4815.      1.  a variable
  4816.  
  4817.      2.  a constant
  4818.  
  4819.      3.  a function designator
  4820.  
  4821.      4.  a component of a value
  4822.  
  4823.      5.  a variable referenced by a reference value
  4824.  
  4825.  At the extend level, a function can also return an array, record, or
  4826.  set. The same syntax used for variables may be used to denote
  4827.  components of the structures these functions return.
  4828.  
  4829.  This feature also allows you to dereference a reference type that is
  4830.  returned by a function. However, you may only use the function designator
  4831.  as a value, not as a variable. For example, the following is illegal:
  4832.  
  4833.       F (X, Y)^ := 42;
  4834.  
  4835.  Also at the extend level, you may declare constants of a structured type.
  4836.  Components of a structured constant use the same syntax as variables of the
  4837.  same type. See Section 10.6, "Constant Expressions," for further discussion
  4838.  of this topic.
  4839.  
  4840.  Examples of structured constant components:
  4841.  
  4842.       TYPE REAL3 = ARRAY [1..3] OF REAL;
  4843.       {an array type}
  4844.       CONST PIES = REAL3 (3.14, 6.28, 9.42);
  4845.       {an array constant}
  4846.         .
  4847.         .
  4848.         X := PIES [1] * PIES [3];
  4849.         {i.e., 3.14 * 9.42}
  4850.         Y := REAL3 (1.1, 2.2, 3.3) [2];
  4851.         {i.e., 2.2}
  4852.  
  4853.  
  4854.  11.4.1  Components of Entire Variables and Values
  4855.  
  4856.  
  4857.  At the standard level, a variable identifier denotes an entire
  4858.  variable. A variable, function designator, or constant denotes an entire
  4859.  value.
  4860.  
  4861.  A component of a variable or value is denoted by the identifier
  4862.  followed by a selector that specifies the component. The form of a selector
  4863.  depends on the type of structure (array, record, file, or reference).
  4864.  
  4865.  
  4866.  11.4.1.1  Indexed Variables and Values
  4867.  
  4868.  A component of an array is denoted by the array variable or value,
  4869.  followed by an index expression. The index expression must be assignment
  4870.  compatible with the index type in the array type declaration. An index
  4871.  type must always be an ordinal type. The index itself must be enclosed in
  4872.  brackets following the array identifier.
  4873.  
  4874.  Examples of indexed variables and values:
  4875.  
  4876.       ARRAY_OF_CHAR ['C']
  4877.       {Denotes the Cth element.}
  4878.  
  4879.       'STRING CONSTANT' [6]
  4880.       {Denotes the 6th element, the letter 'G'.}
  4881.  
  4882.       BETAMAX [12] [-3]
  4883.       BETAMAX [12,-3]
  4884.       {These two say the same thing.}
  4885.  
  4886.       ARRAY_FUNCTION (A, B) [C, D]
  4887.       {Denotes a component of a two-dimensional array}
  4888.       {returned by ARRAY_FUNCTION (A, B). A and B are}
  4889.       {actual parameters.}
  4890.  
  4891.  You may specify the current length of an LSTRING variable, LSTR, in either
  4892.  of two ways:
  4893.  
  4894.      1.  with the notation LSTR [0], to access the length as a CHAR
  4895.          component
  4896.  
  4897.      2.  with the notation LSTR.LEN, to access the length as a BYTE value
  4898.  
  4899.  
  4900.  11.4.1.2  Field Variables and Values
  4901.  
  4902.  A component of a record is denoted by the record variable or value
  4903.  followed by the field identifier for the component. Fields are separated by
  4904.  the period (.). In a WITH statement, you give the record variable or value
  4905.  only once. Within the WITH statement, you may use the field identifier of a
  4906.  record variable directly.
  4907.  
  4908.  Examples of field variables and values:
  4909.  
  4910.       PERSON.NAME := 'PETE'
  4911.  
  4912.       PEOPLE.DRIVERS.NAME := 'JOAN'
  4913.  
  4914.       WITH PEOPLE.DRIVERS DO NAME := 'GERI'
  4915.  
  4916.       RECURSING_FUNC ('XYZ').BETA
  4917.       {Selects BETA field of record returned}
  4918.       {by the function named RECURSIVE_FUNC.}
  4919.  
  4920.       COMPLEX_TYPE (1.2, 3.14).REAL_PART
  4921.  
  4922.  Record field notation also applies to files for FCBFQQ fields, to address
  4923.  type values for numeric representations, and to LSTRINGs for the current
  4924.  length.
  4925.  
  4926.  
  4927.  11.4.1.3  File Buffers and Fields
  4928.  
  4929.  At any time, only one component of a file is accessible. The accessible
  4930.  component is determined by the current file position and represented by the
  4931.  buffer variable. Depending on the status of the buffer variable, the
  4932.  fetching process may first read the value from the file. (This is called
  4933.  "lazy evaluation"; see Section 16.1.5, "Lazy Evaluation," for details.)
  4934.  
  4935.  If a file buffer variable is passed as a reference parameter or used
  4936.  as a record of a WITH statement, the compiler issues a warning to alert you
  4937.  to the fact that the value of the buffer variable may not be correct after
  4938.  the position of the file is changed with a GET or PUT procedure.
  4939.  
  4940.  Examples of file reference variables:
  4941.  
  4942.       INPUT^
  4943.       ACCOUNTS_PAYABLE.FILE^
  4944.  
  4945.  
  4946.  11.4.2  Reference Variables
  4947.  
  4948.  
  4949.  Reference variables or values denote data that refers to some data
  4950.  type.  There are three kinds of reference variables and values:
  4951.  
  4952.      1.  pointer variables and values
  4953.  
  4954.      2.  ADR variables and values
  4955.  
  4956.      3.  ADS variables and values
  4957.  
  4958.  In general, a reference variable or value "points" to a data object.
  4959.  Thus, the value of a reference variable or value is a reference to that
  4960.  data object. To obtain the actual data object pointed to, you must
  4961.  "dereference" the reference variable by appending an up arrow (^) to the
  4962.  variable or value.
  4963.  
  4964.  Example using pointer values:
  4965.  
  4966.       VAR P, Q : ^INTEGER;
  4967.       {P and Q are pointers to integers.}
  4968.  
  4969.       NEW (P); NEW (Q);
  4970.       {P and Q are assigned reference values to}
  4971.       {regions in memory corresponding to data}
  4972.       {objects of type INTEGER.}
  4973.  
  4974.       P := Q;
  4975.       {P and Q now point to the same region}
  4976.       {in memory.}
  4977.  
  4978.       P^:= 123;
  4979.       {Assigns the value 123 to the INTEGER value}
  4980.       {pointed to by P.  Since Q points to this}
  4981.       {location as well, Q^ is also assigned 123.}
  4982.  
  4983.  Using NIL^ is an error (since a NIL pointer does not reference anything).
  4984.  At the extend level, you may also append an up arrow (^) to a
  4985.  function designator for a function that returns a pointer or address type.
  4986.  In this case, the up arrow denotes the value referenced by the return
  4987.  value. This variable cannot be assigned to or passed as a reference
  4988.  parameter.
  4989.  
  4990.  Examples of functions returning reference values:
  4991.  
  4992.  
  4993.       DATA1 := FUNK1 (I, J)^
  4994.       {FUNK1 returns a reference value. The up arrow}
  4995.       {dereferences the reference value returned,}
  4996.       {assigning the referenced data to DATA1.}
  4997.  
  4998.       DATA2 := FUNK2 (K, L)^.FOO [2]
  4999.       {FUNK2 returns a reference value. The up arrow}
  5000.       {dereferences the reference value returned. In}
  5001.       {this case, the dereferenced value is a record.}
  5002.       {The array component FOO [2] of that record is}
  5003.       {assigned to the variable DATA2.}
  5004.  
  5005.  If P is of type ADR OF some type, then P.R denotes the address value of
  5006.  type WORD.  If P is of type ADS OF some type, then P.R denotes the offset
  5007.  portion of the address and P.S denotes the segment portion of the address.
  5008.  Both portions are of type WORD.
  5009.  
  5010.  Examples of address variables:
  5011.  
  5012.       BUFF_ADR.R
  5013.       DATA_AREA.S
  5014.  
  5015.  
  5016.  11.5  Attributes
  5017.  
  5018.  
  5019.  At the extend level of MS-Pascal, a variable declaration or the heading
  5020.  of a procedure or function may include one or more attributes. A variable
  5021.  attribute gives special information about the variable to the compiler.
  5022.  
  5023.  Table 11.1 displays the attributes provided by MS-Pascal for
  5024.  variables.
  5025.  
  5026.  
  5027.  Table 11.1
  5028.  Attributes for Variables
  5029. ╓┌─────────────────┌─────────────────────────────────────────────────────────╖
  5030.  Attribute         Variable
  5031.  ───────────────────────────────────────────────────────────────────────────
  5032.  STATIC            Allocated at a fixed location, not on the stack
  5033.  
  5034.  PUBLIC            Accessible by other modules with EXTERN, implies STATIC
  5035.  
  5036.  EXTERN            Declared PUBLIC in another module, implies STATIC
  5037.  
  5038.  ORIGIN            Located at specified address, implies STATIC
  5039.  
  5040.  PORT              I/O address, implies STATIC
  5041.  
  5042.  Attribute         Variable
  5043. 
  5044.  READONLY          Cannot be altered or written to
  5045.  
  5046.  The EXTERN attribute is also a procedure and function directive; PUBLIC and
  5047.  ORIGIN are also procedure and function attributes. See Section 14.3,
  5048.  "Attributes and Directives," for a discussion of procedure and function
  5049.  attributes and directives. The following sections, 11.5.1 through 11.5.5,
  5050.  discuss each of the variable attributes in detail.
  5051.  
  5052.  You may only give attributes for variables in a VAR section. Specifying
  5053.  variable attributes in a TYPE section or a procedure or function parameter
  5054.  list is not permitted.
  5055.  
  5056.  You give one or more attributes in the variable declaration, enclosed
  5057.  in brackets and separated by commas (if specifying more than one
  5058.  attribute).
  5059.  
  5060.  The brackets may occur in either of two places:
  5061.  
  5062.      1.  An attribute in brackets after a variable identifier in a VAR
  5063.          section applies to that variable only.
  5064.  
  5065.      2.  An attribute in brackets after the reserved word VAR applies to all
  5066.          of the variables in the section.
  5067.  
  5068.  Examples that specify variable attributes:
  5069.  
  5070.       VAR A, B, C [EXTERN] : INTEGER;
  5071.       {Applies to C only.}
  5072.  
  5073.       VAR [PUBLIC] A, B, C  : INTEGER;
  5074.       {Applies to A, B, and C.}
  5075.  
  5076.       VAR [PUBLIC] A, B, C [ORIGIN 16 1000] : INTEGER;
  5077.       {A, B, and C are all PUBLIC. ORIGIN of C}
  5078.       {is the absolute hexadecimal address 1000.}
  5079.  
  5080.  
  5081.  11.5.1  The STATIC Attribute
  5082.  
  5083.  
  5084.  The STATIC attribute gives a variable a unique, fixed location in
  5085.  memory.  This is in contrast to a procedure or function variable that
  5086.  is allocated on the stack or one that is dynamically allocated on the heap.
  5087.  Use of STATIC variables can save time and code space, but increases data
  5088.  space.
  5089.  
  5090.  All variables at the program, module, or unit level are automatically
  5091.  assigned a fixed memory location and given the STATIC attribute.
  5092.  
  5093.  Functions and procedures that use STATIC variables can execute
  5094.  recursively, but STATIC variables must be used only for data common to
  5095.  all invocations.  Since most of the other variable attributes imply the
  5096.  STATIC attribute, the trade-off between savings in time and code space or
  5097.  reduced data space applies to the PUBLIC, EXTERN, ORIGIN, and PORT
  5098.  attributes as well.
  5099.  
  5100.  Files declared in a procedure or function with the STATIC attribute
  5101.  are initialized when the routine is entered; they are closed when the
  5102.  routine terminates like other files. However, other STATIC variables are
  5103.  only initialized before program execution. This means that, except for open
  5104.  FILE variables, STATIC variables can be used to retain values between
  5105.  invocations of a procedure or function.
  5106.  
  5107.  Examples of STATIC variable declarations:
  5108.  
  5109.       VAR VECTOR [STATIC] : ARRAY [0..MAXVEC] OF INTEGER;
  5110.       VAR [STATIC] I, J, K : 0..MAXVEC;
  5111.  
  5112.  The STATIC attribute does not apply to procedures or functions, as do some
  5113.  other attributes.
  5114.  
  5115.  
  5116.  11.5.2  The PUBLIC and EXTERN Attributes
  5117.  
  5118.  
  5119.  The PUBLIC attribute indicates a variable that may be accessed by other
  5120.  loaded modules; the EXTERN attribute identifies a variable that resides in
  5121.  some other loaded module.  The identifier is passed to the target linker in
  5122.  the generated code object file (where it may be truncated if the linker
  5123.  imposes a length restriction).
  5124.  
  5125.  Variables given the PUBLIC or EXTERN attribute are implicitly STATIC.
  5126.  
  5127.  Examples of PUBLIC and EXTERN variable declarations:
  5128.  
  5129.       VAR [EXTERN] GLOBE1, GLOBE2 : INTEGER;
  5130.       {The variables GLOBE1 and GLOBE2 are declared}
  5131.       {EXTERN, meaning that they must be declared}
  5132.       {PUBLIC in some other loaded module.}
  5133.  
  5134.       VAR BASE_PAGE [PUBLIC, ORIGIN #12FE] : BYTE;
  5135.       {The variable BASE_PAGE is located at 12FE,}
  5136.       {hexadecimal. Because it is also PUBLIC, it can}
  5137.       {be accessed from other loaded modules that}
  5138.       {declare BASE_PAGE with the EXTERN attribute.}
  5139.  
  5140.  PUBLIC variables are usually allocated by the compiler, unless you also
  5141.  give them an ORIGIN. Giving a variable both the PUBLIC and ORIGIN
  5142.  attributes tells the loader that a global name has an absolute address.
  5143.  PUBLIC cannot be combined with PORT.
  5144.  
  5145.  If both PUBLIC and ORIGIN are present, the compiler does not need the
  5146.  loader to resolve the address.  However, the identifier is still passed to
  5147.  the linker for use by other modules.
  5148.  
  5149.  EXTERN variables are not allocated by the compiler.  Nor do they have
  5150.  an ORIGIN, since giving both EXTERN and ORIGIN implies two different ways
  5151.  to access the variable.  The reserved word EXTERNAL is synonymous with
  5152.  EXTERN. This increases portability from other Pascals, since others
  5153.  commonly use one of the two.
  5154.  
  5155.  Variables in the interface of a unit are automatically given either
  5156.  the PUBLIC or EXTERN attribute.  If a program, module, or unit USES an
  5157.  interface, its variables are made EXTERN; if you compile the IMPLEMENTATION
  5158.  of the interface, its variables are made PUBLIC.
  5159.  
  5160.  
  5161.  11.5.3  The ORIGIN and PORT Attributes
  5162.  
  5163.  
  5164.  The ORIGIN attribute directs the compiler to locate a variable at a
  5165.  given memory address; the PORT attribute specifies some kind of I/O
  5166.  address. In either case, the address must be a constant of any ordinal
  5167.  type. I/O ports, interrupt vectors, operating system data, and other
  5168.  related data can be accessed with ORIGIN or PORT variables.
  5169.  
  5170.  Examples of ORIGIN and STATIC variable declarations:
  5171.  
  5172.       VAR KEYBOARDP [PORT 16#FFF2] : CHAR;
  5173.       VAR INTRVECT [ORIGIN 8#200] : WORD;
  5174.  
  5175.  Variables with ORIGIN or PORT attributes are implicitly STATIC.  Also, they
  5176.  inhibit common subexpression optimization.  For example, if GATE has the
  5177.  ORIGIN attribute, the two statements X := GATE; Y := GATE; access GATE
  5178.  twice in the order given, instead of using the first value for both
  5179.  assignments. This ensures correct operation if GATE is a memory-mapped
  5180.  input port. However, if GATE is passed as a reference parameter,
  5181.  references to the parameter may be optimized away. For this reason, PORT
  5182.  variables cannot be passed as reference parameters.
  5183.  
  5184.  ORIGIN and PORT variables are never allocated or initialized by the
  5185.  compiler. The associated address only indicates where the variable is
  5186.  found.  ORIGIN always implies a memory address, but the meaning of PORT
  5187.  varies with the implementation.
  5188.  
  5189.  In most implementations, I/O is assumed to be memory mapped, so PORT
  5190.  is just a synonym for ORIGIN. Other implementations use the machine's
  5191.  native input and output instructions. Still others call port input and
  5192.  output routines for every access.
  5193.  
  5194.  For more information on the PORT attribute, see Appendix B, "Version
  5195.  Specifics," in your Microsoft Pascal Compiler User's Guide.
  5196.  
  5197.  Giving the PORT and ORIGIN attributes in brackets immediately
  5198.  following the VAR keyword is ambiguous and generates an error during
  5199.  compilation. (It would be unclear to the compiler whether all variables
  5200.  following should be at the same address or whether addresses should be
  5201.  assigned sequentially.)
  5202.  
  5203.        VAR [ORIGIN 0] FIRST, SECOND : BYTE;  {ILLEGAL!}
  5204.  
  5205.  ORIGIN (but not PORT) permits a segmented address using "segment: offset"
  5206.  notation.
  5207.  
  5208.       VAR SEGVECT [ORIGIN 16#0001 : 16#FFFE] : WORD;
  5209.  
  5210.  Currently, a variable with a segmented ORIGIN cannot be used as the control
  5211.  variable in a FOR statement.
  5212.  
  5213.  
  5214.  11.5.4  The READONLY Attribute
  5215.  
  5216.  
  5217.  The READONLY attribute prevents assignments to a variable.  It also
  5218.  prevents the variable being passed as a VAR or VARS parameter.  Also, a
  5219.  READONLY variable cannot be read with a READ statement or used as a FOR
  5220.  control variable.  You may use READONLY with any of the other attributes.
  5221.  
  5222.  Examples of READONLY variable declarations:
  5223.  
  5224.       VAR INPORT [PORT 12, READONLY] : BYTE;
  5225.       {INPORT is a READONLY PORT variable.}
  5226.  
  5227.       VAR [READONLY] I, J [PUBLIC], K [EXTERN] : INTEGER;
  5228.       {I, J, and K are all READONLY;}
  5229.       {J is also PUBLIC; K is also EXTERN.}
  5230.  
  5231.  CONST and CONSTS parameters, as well as FOR loop control variables (while
  5232.  in the body of the loop), are automatically given the READONLY attribute.
  5233.  READONLY is the only variable attribute that does not imply STATIC
  5234.  allocation.  A variable that is both READONLY and either PUBLIC or EXTERN
  5235.  in one source file is not necessarily READONLY when used in another source
  5236.  file. The READONLY attribute does not apply to procedures and functions.
  5237.  
  5238.  
  5239.  11.5.5  Combining Attributes
  5240.  
  5241.  
  5242.  You may give a variable multiple attributes. Separate the attributes with
  5243.  commas and enclose the list in brackets, as shown:
  5244.  
  5245.       VAR [STATIC]
  5246.       X, Y, Z [ORIGIN #FFFE, READONLY] : INTEGER;
  5247.  
  5248.  In this example, Z is a STATIC, READONLY variable with an ORIGIN at
  5249.  hexadecimal FFFE. These rules apply when you are combining attributes:
  5250.  
  5251.      1.  If you give a variable the EXTERN attribute, you may not give it
  5252.          the PORT, ORIGIN, or PUBLIC attributes in the current compiland.
  5253.  
  5254.      2.  If you give a variable the PORT attribute, you may not give it the
  5255.          ORIGIN, PUBLIC, or EXTERN attributes at all.
  5256.  
  5257.      3.  If you give a variable the ORIGIN attribute, you may not give it
  5258.          the PORT or EXTERN attributes. However, you may combine ORIGIN with
  5259.          PUBLIC.
  5260.  
  5261.      4.  If you give a variable the PUBLIC attribute, you may not give it
  5262.          the PORT or EXTERN attributes. However, you may combine PUBLIC with
  5263.          ORIGIN.
  5264.  
  5265.      5.  You may use STATIC and READONLY with any other attributes.
  5266.  
  5267.  
  5268.  
  5269.  Chapter 12  Expressions
  5270.  
  5271.  ───────────────────────────────────────────────────────────────────────────
  5272.  
  5273.  12.1  Simple Type Expressions
  5274.  
  5275.  12.2  Boolean Expressions
  5276.  
  5277.  12.3  Set Expressions
  5278.  
  5279.  12.4  Function Designators
  5280.  
  5281.  12.5  Evaluating Expressions
  5282.  
  5283.  12.6  Other Features of Expressions
  5284.  
  5285.         12.6.1  The EVAL Procedure
  5286.  
  5287.         12.6.2  The RESULT Function
  5288.  
  5289.         12.6.3  The RETYPE Function
  5290.  
  5291.  
  5292.  
  5293.  Expressions are constructions that evaluate to values. Table 12.1
  5294.  illustrates a variety of expressions, which, if A = 1 and B = 2, evaluate
  5295.  to the value shown.
  5296.  
  5297.  
  5298.           Table 12.1
  5299.           Expressions
  5300. ╓┌──────────────────────────────────┌────────────────────────────────────────╖
  5301.           Expression                Value
  5302.           ────────────────────────────────────────────
  5303.           2                         2
  5304.  
  5305.           A                         1
  5306.  
  5307.           A + 2                     3
  5308.  
  5309.           (A + 2)                   3
  5310.  
  5311.           (A + 2) * (B - 3)        -3
  5312.  
  5313.  The operands in an expression may be a value or any other expression.
  5314.  When any operator is applied to an expression, that expression is called an
  5315.  operand.  With parentheses for grouping and operators that use other
  5316.  expressions, you can construct expressions as long and complicated as
  5317.  desired.
  5318.  
  5319.  The available operators, in the order in which they are applied, are
  5320.  as follows:
  5321.  
  5322.      1.  Unary
  5323.  
  5324.          NOT  [ADR ADS]
  5325.  
  5326.      2.  Multiplying
  5327.  
  5328.          * / DIV MOD AND (ISR SHL SHR)
  5329.  
  5330.      3.  Adding
  5331.  
  5332.          + - OR (XOR)
  5333.  
  5334.      4.  Relational
  5335.  
  5336.          =  <>  <=  >=  < > IN
  5337.  
  5338.  Operators shown above in parentheses are available only at the extend
  5339.  level of Microsoft Pascal, those in brackets only at the system level.
  5340.  
  5341.  A standard Pascal expression is either a value or the result of
  5342.  applying an operator to one or two values. Although a value can be of
  5343.  almost any type, most MS-Pascal operators only apply to the following
  5344.  types:
  5345.  
  5346.       INTEGER     INTEGER4
  5347.       WORD        BOOLEAN
  5348.       REAL        SET
  5349.  
  5350.  The relational operators also apply for the CHAR, enumerated, string,
  5351.  and reference types. For all operators (except the set operator IN),
  5352.  operands must have compatible types.
  5353.  
  5354.  
  5355.  12.1  Simple Type Expressions
  5356.  
  5357.  
  5358.  As a rule, the operands and the value resulting from an operation are
  5359.  all of the same type. Occasionally, however, the type of an operand is
  5360.  changed to the type required by an operator.
  5361.  
  5362.  This conversion occurs on two levels: one for constant operands only,
  5363.  and one for all operands. INTEGER to WORD conversion occurs for constant
  5364.  operands only; conversion from INTEGER to REAL and from INTEGER or WORD to
  5365.  INTEGER4 occurs for all operands.
  5366.  
  5367.  If necessary in constant expressions, INTEGER values change to WORD
  5368.  type. Be careful when mixing INTEGER and WORD constants in expressions.
  5369.  For example, if CBASE is the constant 16#C000 and DELTA is the constant -1,
  5370.  the following expression gives a WORD overflow:
  5371.  
  5372.       WRD (CBASE) + DELTA
  5373.  
  5374.  The overflow occurs because DELTA is converted to the WORD value 16#FFFF,
  5375.  and 16#C000 plus 16#FFFF is greater than MAXWORD. However, the following
  5376.  would work:
  5377.  
  5378.       WRD (ORD (CBASE) + DELTA)
  5379.  
  5380.  This expression gives the INTEGER value -16385, which changes to WORD
  5381.  16#BFFF. If conversion is needed by an operator or for an assignment, the
  5382.  compiler makes the following conversions:
  5383.  
  5384.      1.  from INTEGER to REAL or INTEGER4
  5385.  
  5386.      2.  from WORD to INTEGER4
  5387.  
  5388.  The following rules determine the type of the result of an expression
  5389.  involving these simple types:
  5390.  
  5391.      1.  +  -  *
  5392.  
  5393.          These operators affect INTEGERs, REALs, WORDs, and INTEGER4s,
  5394.          as shown in the following examples:
  5395.  
  5396.          +123
  5397.          A + 123
  5398.          -23.4
  5399.          A - 8
  5400.          A * B * 3
  5401.  
  5402.          Mixtures of REALs with INTEGERs and  of INTEGER4s with INTEGERs or
  5403.          WORDs are allowed. Where both operands are of the same type, the
  5404.          resulting type is the type of the operands. If either operand is
  5405.          REAL, the resulting type is REAL; otherwise, if either operand is
  5406.          INTEGER4, the resulting type is INTEGER4.
  5407.  
  5408.          Unary plus (+) and minus (-) are supported, along with the binary
  5409.          forms. Unary minus on a WORD type is two's complement (NOT is
  5410.          one's complement); since there are no negative WORD values, this
  5411.          always generates a warning.
  5412.  
  5413.          Because unary minus has the same precedence level as the adding
  5414.          operators:
  5415.  
  5416.             (X * -1)      {Is illegal}
  5417.             (-256 AND X)  {Is interpreted as -(256 AND X)}
  5418.  
  5419.      2.  /
  5420.  
  5421.          This is a "true" division operator. The result is always REAL.
  5422.          Operands may be INTEGER or REAL (not WORD or INTEGER4).
  5423.  
  5424.          Examples of division:
  5425.  
  5426.             34 / 26.4  =  1.28787...
  5427.             18 / 6     =  3.00000...
  5428.  
  5429.      3.  DIV   MOD
  5430.  
  5431.          These are the operators for integer divide quotient and remainder,
  5432.          respectively.  The left operand (dividend) is divided by the right
  5433.          operand (divisor).
  5434.  
  5435.          Examples of integer division:
  5436.  
  5437.             123 MOD  5 =  3
  5438.            -123 MOD  5 = -3  {Sign of result is}
  5439.                              {sign of dividend }
  5440.             123 MOD -5 =  3
  5441.             1.3 MOD  5       {Illegal with REAL operands}
  5442.             123 DIV  5 = 24
  5443.             1.3 DIV  5       {Illegal with REAL operands}
  5444.  
  5445.          Both operands must be of the same type: INTEGER, WORD, or INTEGER4
  5446.          (not REAL). The sign of the remainder (MOD) is always the sign of
  5447.          the dividend.
  5448.  
  5449.          MS-Pascal differs from the current draft ISO standard with respect
  5450.          to the semantics for DIV and MOD with negative operands, but the
  5451.          resulting code is more efficient. Programs intended to be portable
  5452.          should not use DIV and MOD unless both operands are positive.
  5453.  
  5454.      4.  AND   OR   XOR   NOT
  5455.  
  5456.          These extend level operators are bitwise logical functions.
  5457.          Operands must be INTEGER or WORD or INTEGER4 (never a mixture), and
  5458.          cannot be REAL. The result has the type of the operands.
  5459.  
  5460.          NOT is a bitwise one's complement operation on the single operand.
  5461.          If an INTEGER variable V has the value MAXINT, NOT V gives the
  5462.          illegal INTEGER value -32768. This generates an error if the
  5463.          initialization switch is on and the value is used later in a
  5464.          program.
  5465.  
  5466.          Given the following initial INTEGER values,
  5467.  
  5468.          X = 2#1111000011110000
  5469.          Y = 2#1111111100000000
  5470.  
  5471.          AND, OR, XOR, and NOT perform the following functions:
  5472.  
  5473.          X AND Y    1111000011110000
  5474.                     1111111100000000
  5475.                     ----------------
  5476.                     1111000000000000
  5477.  
  5478.          X OR Y     1111000011110000
  5479.                     1111111100000000
  5480.                     ----------------
  5481.                     1111111111110000
  5482.  
  5483.          X XOR Y    1111000011110000
  5484.                     1111111100000000
  5485.                     ----------------
  5486.                     0000111111110000
  5487.  
  5488.          NOT X      1111000011110000
  5489.                     ----------------
  5490.                     0000111100001111
  5491.  
  5492.      5.  SHL   SHR   ISR
  5493.  
  5494.          These extend level operators provide bitwise shifting functions.
  5495.  
  5496.          SHL and SHR are logical shifts left and right. ISR is an integer
  5497.          (signed) arithmetic shift right: the sign bit is always propagated,
  5498.          even on a WORD type operand. Since the compiler cannot generate a
  5499.          simple right shift for INTEGER division (-1 DIV 2 would be
  5500.          incorrect) and division is a very time-consuming operation, SHR or
  5501.          ISR could be used instead of DIV where appropriate.
  5502.  
  5503.          Operands must be both INTEGER, both WORD, or both INTEGER4;
  5504.          they cannot be REAL. The result has the same type as the operands.
  5505.  
  5506.          The left operand is shifted, and the right operand is the shift
  5507.          count in bits. A shift count less than 0 or greater than 32
  5508.          produces undefined results and generates an error message if the
  5509.          range checking switch is on. Shifts never cause overflow errors;
  5510.          shifted bits are simply lost.
  5511.  
  5512.          Given that X = 2#1111111100000000, the shifting functions
  5513.          would perform the following operations:
  5514.  
  5515.          X         1111111100000000
  5516.          X SHL 1   1111111000000000
  5517.          X SHR 1   0111111110000000
  5518.          X ISR 1   1111111110000000 {sign extension}
  5519.  
  5520.  
  5521.  12.2  Boolean Expressions
  5522.  
  5523.  
  5524.  The Boolean operators at the standard level of MS-Pascal are:
  5525.  
  5526.       NOT              AND              OR
  5527.       =                <                >
  5528.       <>               <=               >=
  5529.  
  5530.  XOR is available at the extend and systems levels.
  5531.  
  5532.  You may also use P <> Q as an exclusive OR function. Since
  5533.  FALSE < TRUE, P <= Q denotes the Boolean operation "P implies Q."
  5534.  Furthermore, the Boolean operators AND and OR are not the same as
  5535.  the WORD and INTEGER operators of the same name that are bitwise
  5536.  logical functions. The Boolean AND and OR operators may or may not
  5537.  evaluate their operations. The following example illustrates the
  5538.  danger of assuming that they don't:
  5539.  
  5540.       WHILE (I <= MAX) AND (V [I] <> T) DO I := I + 1;
  5541.  
  5542.  If array V has an upper bound MAX, then the evaluation of V [I] for I > MAX
  5543.  is a runtime error. This evaluation may or may not take place. Sometimes
  5544.  both operands are evaluated during optimization, and sometimes the
  5545.  evaluation of one may cause the evaluation of the other to be skipped. In
  5546.  the latter case, either operand may be evaluated first.
  5547.  
  5548.  Instead, use the following construction:
  5549.  
  5550.       WHILE I <= MAX DO
  5551.          IF V [I] <> T THEN I := I + 1 ELSE BREAK;
  5552.  
  5553.  See Section 13.3.5, "Sequential Control," for information on using AND THEN
  5554.  and OR ELSE to handle situations, such as the previous example, where tests
  5555.  are examined sequentially.
  5556.  
  5557.  The relational operators produce a Boolean result. The types of the
  5558.  operands of a relational operator (except for IN) must be compatible.
  5559.  If they are not compatible, one must be REAL and the other compatible
  5560.  with INTEGER.
  5561.  
  5562.  Reference types can only be compared with = and <>. To compare an
  5563.  address type with one of the other relational operators, you must use
  5564.  address field notation, as shown:
  5565.  
  5566.       IF (A.R < B.R) THEN statement;
  5567.  
  5568.  Except for the string types STRING and LSTRING, you cannot compare files,
  5569.  arrays, and records as wholes. Two STRING types must have the same upper
  5570.  bound to be compared; two LSTRINGs may have different upper bounds.
  5571.  
  5572.  In LSTRING comparison, characters past the current length are ignored.
  5573.  If the current length of one LSTRING is less than the length of the other
  5574.  and all characters up to the length of the shorter are equal, the compiler
  5575.  assumes the shorter one is "less than" the longer one. However, two
  5576.  LSTRINGs are not considered equal unless all current characters are equal
  5577.  and their current lengths are equal.
  5578.  
  5579.  The six relational operators  =, <>, <=, >=, <, and > have their
  5580.  normal meaning when applied to numeric, enumerated, CHAR, or string
  5581.  operands. Section 12.3, "Set Expressions," discusses the meaning of these
  5582.  relational operators (along with the relational operator IN) when applied
  5583.  to sets. Since the relational operators in Boolean expressions have a
  5584.  lower precedence than AND and OR, the following is incorrect:
  5585.  
  5586.       IF I < 10 AND J = K THEN
  5587.  
  5588.  Instead, you must write:
  5589.  
  5590.       IF (I < 10) AND (J = K) THEN
  5591.  
  5592.  Also, you may not use the numeric types where a Boolean operand is called
  5593.  for. (Some other languages permit this.) For an integer I, the clause IF I
  5594.  THEN is illegal; you must use the following instead:
  5595.  
  5596.       IF I <> 0 THEN
  5597.  
  5598.  Note, however, that MS-Pascal does allow the following:
  5599.  
  5600.       $if I $then
  5601.  
  5602.  The inclusion of special NAN ("Not A Number") values means that a
  5603.  comparison between two real numbers can have a result other than less-than,
  5604.  equal, or greater-than. The numbers can be unordered, meaning one or both
  5605.  are NANs.  An unordered result is the same as "not equal, not less than,
  5606.  and not greater than." For example, if variables A or B are NAN values:
  5607.  
  5608.      1.  A < B is false.
  5609.  
  5610.      2.  A <= B is false.
  5611.  
  5612.      3.  A > B is false.
  5613.  
  5614.      4.  A >= B is false.
  5615.  
  5616.      5.  A = B is false.
  5617.  
  5618.      6.  A <> B is, however, true.
  5619.  
  5620.  REAL comparisons do not follow the same rules as other comparisons in
  5621.  many ways. A < B is not always the same as NOT (B <= A);  this prevents
  5622.  some optimizations otherwise done by the compiler. If A is a NAN, then
  5623.  A <> A is true; in fact, this is a good way to check for a NAN value.
  5624.  
  5625.  
  5626.  12.3  Set Expressions
  5627.  
  5628.  
  5629.  Table 12.2 shows the MS-Pascal operators that apply differently to sets
  5630.  than to other types of expressions.
  5631.  
  5632.  
  5633.       Table 12.2
  5634.       Set Operators
  5635. ╓┌────────────────────────┌──────────────────────────────────────────────────╖
  5636.       Operator            Meaning in Set Operations
  5637.       ──────────────────────────────────────────────────────────────
  5638.       +                   Set union
  5639.       -                   Set difference
  5640.       *                   Set intersection
  5641.       =                   Test set equality
  5642.       <>                  Test set inequality
  5643.       <= and >=           Test subset and superset
  5644.       < and  >            Test proper subset and superset
  5645.       IN                  Test set membership
  5646.  
  5647.  Any operand whose type is SET OF S, where S is a subrange of T, is
  5648.  treated as if it were SET OF T. (T is restricted to the range from 0 to
  5649.  255 or the equivalent ORD values.) Either both operands must be PACKED or
  5650.  neither must be PACKED, unless one operand is a constant or constructed
  5651.  set.
  5652.  
  5653.  With the IN operator, the left operand (an ordinal) must be compatible
  5654.  with the base type of the right operand (a set). The expression X IN B
  5655.  is TRUE if X is a member of the set B, and FALSE otherwise. X can be
  5656.  outside of the range of the base type of B legally. For example, X IN B
  5657.  is always false if the following statements are true:
  5658.  
  5659.       X = 1
  5660.       B = SET OF 2..9
  5661.  
  5662.  (1 is compatible, but not assignment compatible, with 2..9).
  5663.  
  5664.  Angle brackets are set operators only at the extend level of MS-Pascal,
  5665.  since the ISO standard does not support them for sets. They test that
  5666.  a set is a proper subset or superset of another set. Proper subsetting
  5667.  does not permit a set as a subset if the two sets are equal.
  5668.  
  5669.  Expressions involving sets may use the "set constructor," which gives
  5670.  the elements in a set enclosed in square brackets. Each element can be
  5671.  an expression whose type is in the base type of the set or the lower
  5672.  and upper bounds of a range of elements in the base type. Elements cannot
  5673.  be sets themselves.
  5674.  
  5675.  Examples of sets involving set constructors:
  5676.  
  5677.       SET_COLOR := [RED, BLUE..PURPLE] - [YELLOW]
  5678.       SET_NUMBER :=
  5679.          [12, J+K, TRUNC (EXP (X))..TRUNC (EXP (X+1))]
  5680.  
  5681.  Set constructor syntax is similar to CASE constant syntax. If X > Y then
  5682.  [X..Y] denotes the empty set. Empty brackets also denote the empty set and
  5683.  are compatible with all sets. Also, if all elements are constant, a set
  5684.  constructor is the same as a set constant.
  5685.  
  5686.  Like other structured constants, the type identifier for a constant
  5687.  set can be included in a set constant, as in COLORSET [RED..BLUE]. This
  5688.  does not mean that a set constructor with variable elements can be given a
  5689.  type in an expression: NUMBERSET [I..J] is illegal if I or J is a
  5690.  variable.
  5691.  
  5692.  A set constructor such as [I, J,..K] or an untyped set such as [1,
  5693.  5..7], is compatible with either a PACKED or an unpacked set. A typed set
  5694.  constant, such as DIGITS [1, 5..7], is only compatible with sets that are
  5695.  PACKED or unpacked, respectively, in the same way as the explicit type of
  5696.  the constant.
  5697.  
  5698.  
  5699.  12.4  Function Designators
  5700.  
  5701.  
  5702.  A function designator specifies the activation of a function. It
  5703.  consists of the function identifier, followed by a (possibly empty)
  5704.  list of "actual parameters" in parentheses:
  5705.  
  5706.       {Declaration of the function ADD.}
  5707.       FUNCTION ADD (A, B : INTEGER); INTEGER;
  5708.         .
  5709.         .
  5710.       {Use of the function ADD in an expression.}
  5711.       X := ADD (7, X * 4) + 123;
  5712.       {ADD is a function designator.}
  5713.  
  5714.  These actual parameters substitute, position for position, for their
  5715.  corresponding "formal parameters," defined in the function declaration.
  5716.  
  5717.  Parameters can be variables, expressions, procedures, or functions.
  5718.  If the parameter list is empty, the parentheses must be omitted. See
  5719.  Section 14.4, "Procedure and Function Parameters," for more information
  5720.  on parameters.
  5721.  
  5722.  The order of evaluation and binding of the actual parameters varies,
  5723.  depending on the optimizations used. If the $simple metacommand is on, the
  5724.  order is left to right.
  5725.  
  5726.  In most computer languages, functions have two different uses:
  5727.  
  5728.      1.  In the mathematical sense, they take one or more values from a
  5729.          domain to produce a resulting value in a range. In this case, if
  5730.          the function never does anything else (such as assign to a global
  5731.          variable or do input/output), it is called a "pure" function.
  5732.  
  5733.      2.  The second type of function may have side effects, such as changing
  5734.          a static variable or a file. Functions of this second kind are
  5735.          said to be "impure."
  5736.  
  5737.  At the standard level, a function may return either a simple type or a
  5738.  pointer. At the extend level, a function can return any assignable type
  5739.  (i.e., any type except a file or super array).
  5740.  
  5741.  At the standard level, a pointer returned by a function can only be
  5742.  compared, assigned, or passed as a value parameter. At the extend level,
  5743.  however, the usual selection syntax for reference types, arrays, and
  5744.  records is allowed, following the function designator. See Section 11.4,
  5745.  "Using Variables and Values," for more information.
  5746.  
  5747.  Examples of function designators:
  5748.  
  5749.       SIN (X + Y)
  5750.  
  5751.       NEXTCHAR
  5752.  
  5753.       NEXTREC (17)^
  5754.       {Here the function return type}
  5755.       {is a pointer, and the returned}
  5756.       {pointer value is dereferenced.}
  5757.  
  5758.       NAD.NAME [1]
  5759.       {Here the function has no parameters.}
  5760.       {The return type is a record, one}
  5761.       {field of which is an array.}
  5762.       {The identifier for that field is}
  5763.       {NAME. The example above selects}
  5764.       {the first array component of the}
  5765.       {returned record.}
  5766.  
  5767.  It is more efficient to return a component of a structure than to
  5768.  return a structure and then use only one component of it. The compiler
  5769.  treats a function that returns a structure like a procedure, with an extra
  5770.  VAR parameter representing the result of the function. The function's
  5771.  caller allocates an unseen variable (on the stack) to receive the return
  5772.  value, but this "variable" is only allocated during execution of the
  5773.  statement that contains the function invocation.
  5774.  
  5775.  
  5776.  12.5  Evaluating Expressions
  5777.  
  5778.  
  5779.  In cases of ambiguity, an operator at a higher level is applied before
  5780.  one at a lower level. For instance, the following expression evaluates to
  5781.  7 and not to 9:
  5782.  
  5783.       1 + 2 * 3
  5784.  
  5785.  Use parentheses to change operator precedence. Thus, the following
  5786.  evaluates to 9 rather than 7:
  5787.  
  5788.       (1 + 2) * 3
  5789.  
  5790.  If the $simple switch is on, sequences of operators of the same
  5791.  precedence are executed from left to right. If the switch is off, the
  5792.  compiler may rearrange expressions and evaluate common subexpressions only
  5793.  once, in order to generate optimized code. The semantics of the precedence
  5794.  relationships are retained, but normal associative and distributive laws
  5795.  are used. For example,
  5796.  
  5797.       X * 3 + 12
  5798.  
  5799.  is an optimization of:
  5800.  
  5801.       3 * (6 + (X - 2))
  5802.  
  5803.  These optimizations may occasionally give you unexpected overflow errors.
  5804.  For example,
  5805.  
  5806.       (I - 100) + (J - 100)
  5807.  
  5808.  will be optimized into the following:
  5809.  
  5810.       (I + J) - 200
  5811.  
  5812.  This may result in an overflow error, although the original expression did
  5813.  not (e.g., if "I" and "J" were each 16400).
  5814.  
  5815.  An expression in your source file may or may not actually be evaluated
  5816.  when the program runs. For example, the expression F(X + Y) * 0 is always
  5817.  zero, so the subexpression (X + Y) and the function call need not be
  5818.  executed.
  5819.  
  5820.  The compiler does not optimize real expressions as much as, for
  5821.  example, integer expressions, to make sure that the result of a real
  5822.  expression is always what a simple evaluation of the expression, as given,
  5823.  would be. For example, the integer expression
  5824.  
  5825.       ((1 + I) - 1) * J
  5826.  
  5827.  is optimized to:
  5828.  
  5829.       I * J
  5830.  
  5831.  but the same expression with real variables is not optimized since the
  5832.  results may be different due to precision loss. Common subexpressions, such
  5833.  as 2 * X in SIN (2 * X) * COS (2 * X), may still be calculated just once
  5834.  and reloaded as necessary, but they are saved in a special 80-bit
  5835.  intermediate precision.
  5836.  
  5837.  The order of evaluation may be fixed by parentheses:
  5838.  
  5839.       (A + B) + C
  5840.  
  5841.  is evaluated by adding A and B first, but
  5842.  
  5843.       A + B + C
  5844.  
  5845.  may be evaluated by adding A and B, B and C, or even A and C first.
  5846.  
  5847.  Any expression can be passed as a CONST or CONSTS parameter or have
  5848.  its "address" found. The expression is calculated and stored in a temporary
  5849.  variable on the stack, and the address of this temporary variable can be
  5850.  used as a reference parameter or in some other address context.
  5851.  
  5852.  To avoid ambiguities, enclose such an expression with operators or
  5853.  function calls in parentheses. For example, to invoke a procedure
  5854.  FOO (CONST X, Y : INTEGER), FOO (I, (J + 14)) must be used instead
  5855.  of FOO (I, J + 14).
  5856.  
  5857.  This implies a subtle distinction in the case of functions. For
  5858.  example:
  5859.  
  5860.       FUNCTION SUM (CONST A, B : INTEGER) : INTEGER;
  5861.       BEGIN
  5862.         SUM := A;
  5863.         IF B <> 0 THEN
  5864.             SUM := SUM (SUM, (SUM (B, 0) - 1)) + 1;
  5865.       END;
  5866.  
  5867.  In this example, SUM is called recursively, subtracting one from B until B
  5868.  is zero.
  5869.  
  5870.  The use of a function identifier in a WITH statement follows a similar
  5871.  rule. For example, given a parameterless function, COMPLEX, which returns a
  5872.  record, "WITH COMPLEX" means "WITH the current value of the function."
  5873.  This can only occur inside the COMPLEX function itself. However, "WITH
  5874.  (COMPLEX)" causes the function to be called and the result assigned to a
  5875.  temporary local variable.
  5876.  
  5877.  Another way to describe this is to distinguish between "address" and
  5878.  "value" phrases. The left-hand side of an assignment, a reference
  5879.  parameter, the ADR and ADS operators, and the WITH statement all need an
  5880.  address. The right-hand side of an assignment and a value parameter all
  5881.  need a value.
  5882.  
  5883.  If an address is needed but only a value, such as a constant or an
  5884.  expression in parentheses, is available, the value must be put into memory
  5885.  so it has an address. For constants, the value goes in static memory;  for
  5886.  expressions, the value goes in stack (local) memory. A function identifier
  5887.  refers to the current value of the function as an address, but causes the
  5888.  function to be called as a value.
  5889.  
  5890.  Finally, in the scope of a function, the intrinsic procedure RESULT
  5891.  permits a reference to the current value of a function instead of invoking
  5892.  it recursively. For a function F, this means ADR F and ADR RESULT (F) are
  5893.  the same:  the address of the current value of F.  RESULT forces use of the
  5894.  current value in the same way that putting the function in parentheses, as
  5895.  in (F(X)), forces evaluation of the function.
  5896.  
  5897.  
  5898.  12.6  Other Features of Expressions
  5899.  
  5900.  
  5901.  EVAL and RESULT are two procedures available at the extend level for
  5902.  use with expressions. EVAL obtains the effect of a procedure from a
  5903.  function; RESULT yields the current value of a function within a function
  5904.  or nested procedure or function.
  5905.  
  5906.  At the system level, the function RETYPE allows you to change the type
  5907.  of a value.
  5908.  
  5909.  
  5910.  12.6.1  The EVAL Procedure
  5911.  
  5912.  
  5913.  EVAL evaluates its parameters without actually calling anything.
  5914.  Generally, you use EVAL to obtain the effect of a procedure from a
  5915.  function. In such cases, the values returned by functions are of no
  5916.  interest, so EVAL is only useful for functions with side effects. For
  5917.  example, a function that advances to the next item and also returns the
  5918.  item might be called in EVAL just to advance to the next item, since there
  5919.  is no need to obtain a function return value.
  5920.  
  5921.  Examples of the EVAL procedure:
  5922.  
  5923.       EVAL (NEXTLABEL (TRUE))
  5924.       EVAL (SIDEFUNC (X, Y), INDEX (4), COUNT)
  5925.  
  5926.  
  5927.  12.6.2  The RESULT Function
  5928.  
  5929.  
  5930.  Within the scope of a function, the intrinsic procedure RESULT permits a
  5931.  reference to the current value of a function instead of invoking it
  5932.  recursively. For a function F, this means ADR F and ADR RESULT (F) are the
  5933.  same; that is, the address of the current value of F. RESULT forces use of
  5934.  the current value in the same way that putting the function in parentheses
  5935.  as in (F (X)) forces evaluation of the function.
  5936.  
  5937.  Examples of the RESULT function:
  5938.  
  5939.       FUNCTION FACTORIAL (I : INTEGER) : INTEGER;
  5940.       BEGIN
  5941.         FACTORIAL := 1;  WHILE I > 1 DO
  5942.         BEGIN
  5943.           FACTORIAL := I * RESULT (FACTORIAL);
  5944.           I := I - 1
  5945.         END
  5946.       END;
  5947.  
  5948.      FUNCTION ABSVAL (I : INTEGER) : INTEGER;
  5949.      BEGIN
  5950.        ABSVAL := I;
  5951.        IF I < 0 THEN ABSVAL := -RESULT (ABSVAL)
  5952.      END;
  5953.  
  5954.  
  5955.  12.6.3  The RETYPE Function
  5956.  
  5957.  
  5958.  Occasionally, you need to change the type of a value.  You can do this with
  5959.  the RETYPE function, available at the system level of MS-Pascal. If the new
  5960.  type is a structure, RETYPE can be followed by the usual selection syntax.
  5961.  
  5962.  Examples of the RETYPE function:
  5963.  
  5964.       RETYPE (COLOR, 3)   {inverse of ORD}
  5965.       RETYPE (STRING2, I * J + K) [2]   {effect may vary}
  5966.  
  5967.  You must use RETYPE with caution: it works on the memory byte level and
  5968.  ignores whether the low order byte of a two-byte number comes first or
  5969.  second in memory.
  5970.  
  5971.  
  5972.  
  5973.  Chapter 13  Statements
  5974.  
  5975.  ───────────────────────────────────────────────────────────────────────────
  5976.  
  5977.  13.1  The Syntax of Pascal Statements
  5978.  
  5979.         13.1.1  Labels
  5980.  
  5981.         13.1.2  Separating Statements
  5982.  
  5983.         13.1.3  The Reserved Words BEGIN and END
  5984.  
  5985.  13.2  Simple Statements
  5986.  
  5987.         13.2.1  Assignment Statements
  5988.  
  5989.         13.2.2  Procedure Statements
  5990.  
  5991.         13.2.3  The GOTO Statement
  5992.  
  5993.         13.2.4  The BREAK, CYCLE, and RETURN Statements
  5994.  
  5995.  13.3  Structured Statements
  5996.  
  5997.         13.3.1  Compound Statements
  5998.  
  5999.         13.3.2  Conditional Statements
  6000.  
  6001.                  13.3.2.1  The IF Statement
  6002.  
  6003.                  13.3.2.2  The CASE Statement
  6004.  
  6005.         13.3.3  Repetition Statements
  6006.  
  6007.                  13.3.3.1  The WHILE Statement
  6008.  
  6009.                  13.3.3.2  The REPEAT Statement
  6010.  
  6011.                  13.3.3.3  The FOR Statement
  6012.  
  6013.                  13.3.3.4  The BREAK and CYCLE Statements
  6014.  
  6015.         13.3.4  The WITH Statement
  6016.  
  6017.         13.3.5  Sequential Control
  6018.  
  6019.  
  6020.  
  6021.  The body of a program, procedure, or function contains statements.
  6022.  Statements denote actions that the program can execute. This chapter first
  6023.  discusses the syntax of statements and then separates and describes two
  6024.  categories of statements: simple statements and structured statements. A
  6025.  simple statement has no parts that are themselves other statements; a
  6026.  structured statement consists of two or more other statements. Table 13.1
  6027.  lists the statements in each category in Microsoft Pascal.
  6028.  
  6029.  
  6030.           Table 13.1
  6031.           Microsoft Pascal Statement
  6032. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  6033.           Simple                   Structured
  6034.           ────────────────────────────────────────────
  6035.           Assignment (:=)          Compound
  6036.           Procedure                IF/THEN/ELSE
  6037.           GOTO                     CASE
  6038.           BREAK                    FOR
  6039.           CYCLE                    WHILE
  6040.           RETURN                   REPEAT
  6041.           Empty                    WITH
  6042.  
  6043.  
  6044.  13.1  The Syntax of Pascal Statements
  6045.  
  6046.  
  6047.  Pascal statements are separated by a semicolon (;) and enclosed by reserved
  6048.  words such as BEGIN and END. A statement begins, optionally, with a label.
  6049.  Each of these three elements of statement syntax are discussed in the
  6050.  following sections.
  6051.  
  6052.  
  6053.  13.1.1  Labels
  6054.  
  6055.  
  6056.  Any statement referred to by a GOTO statement must have a label. A label
  6057.  at the standard level is one or more digits; leading zeros are ignored.
  6058.  Constant identifiers, expressions, and nondecimal notation cannot serve as
  6059.  labels.
  6060.  
  6061.  All labels must be declared in a LABEL section. At the extend level, a
  6062.  label can also be an identifier.
  6063.  
  6064.  Example using labels and GOTO statements:
  6065.  
  6066.       PROGRAM LOOPS (INPUT, OUTPUT);
  6067.       LABEL 1, HAWAII, MAINLAND;
  6068.  
  6069.       BEGIN
  6070.         MAINLAND : GOTO 1;
  6071.         HAWAII : WRITELN ('Here I am in Hawaii');
  6072.         1 : GOTO HAWAII
  6073.       END.
  6074.  
  6075.  A loop label is any label immediately preceding a looping statement:
  6076.  WHILE, REPEAT, or FOR. At the extend level, a BREAK or CYCLE statement
  6077.  can also refer to a loop label.
  6078.  
  6079.  Both a CASE constant list and a GOTO label may precede a statement, in
  6080.  which case the CASE constants come first and then the GOTO label. In the
  6081.  following example, 321 is a CASE value, 123 is a label:
  6082.  
  6083.       321 : 123 : IF LOOP THEN GOTO 123
  6084.  
  6085.  
  6086.  13.1.2  Separating Statements
  6087.  
  6088.  
  6089.  Semicolons separate statements. Semicolons do not terminate statements.
  6090.  However, since Pascal permits the empty statement, using the semicolon as
  6091.  if it were a statement terminator is rarely disastrous.
  6092.  
  6093.  Example showing semicolon to separate statements:
  6094.  
  6095.       BEGIN
  6096.          10 : WRITELN;
  6097.          A := 2 + 3;
  6098.          GOTO 10
  6099.       END
  6100.  
  6101.  A common error is to terminate the THEN clause in an IF/THEN/ELSE statement
  6102.  with a semicolon. Thus, the following example generates a warning message:
  6103.  
  6104.       IF A = 2 THEN WRITELN;
  6105.       ELSE A = 3
  6106.  
  6107.  Another common error is to put a semicolon after the DO in a WHILE or FOR
  6108.  statement:
  6109.  
  6110.      FOR I := 1 TO 10 DO;
  6111.      BEGIN
  6112.        A[I] := I;
  6113.        B[I] := 10 - I
  6114.      END;
  6115.  
  6116.  The previous example, as written, will "execute" an empty statement ten
  6117.  times, then execute the array assignments once. Since there are
  6118.  occasionally legitimate uses for repeating an empty statement, no
  6119.  warning is given when this occurs.
  6120.  
  6121.  The semicolon also follows the reserved word END at the close of a
  6122.  block of program statements.
  6123.  
  6124.  
  6125.  13.1.3  The Reserved Words BEGIN and END
  6126.  
  6127.  
  6128.  Whenever you want a program to execute a group of statements, instead
  6129.  of a single simple statement, you may enclose the block with the reserved
  6130.  words BEGIN and END.
  6131.  
  6132.  For example, the following group of statements between BEGIN and END
  6133.  will all be executed if the condition in the IF statement is TRUE:
  6134.  
  6135.       IF (MAX > 10) THEN
  6136.       BEGIN
  6137.         MAX = 10;
  6138.         MIN = 0;
  6139.         WRITELN (MAX, MIN)
  6140.       END;
  6141.       WRITELN ('done')
  6142.  
  6143.  At the extend level, you may substitute a pair of square brackets for the
  6144.  pair of keywords BEGIN and END.
  6145.  
  6146.  
  6147.  13.2  Simple Statements
  6148.  
  6149.  
  6150.  A simple statement is one in which no part constitutes another
  6151.  statement. Simple statements in standard Pascal are:
  6152.  
  6153.  
  6154.      1.  the assignment statement
  6155.  
  6156.      2.  the procedure statement
  6157.  
  6158.      3.  the GOTO statement
  6159.  
  6160.      4.  the empty statement
  6161.  
  6162.  The empty statement contains no symbols and denotes no action. It
  6163.  is included in the definition of the language primarily to permit you to
  6164.  use a semicolon after the last in a group of statements enclosed between
  6165.  BEGIN and END.
  6166.  
  6167.  The extend level in MS-Pascal adds three simple statements: BREAK,
  6168.  CYCLE, and RETURN.
  6169.  
  6170.  
  6171.  13.2.1  Assignment Statements
  6172.  
  6173.  
  6174.  The assignment statement replaces the current value of a variable with
  6175.  a new value, which you specify as an expression. Assignment is denoted
  6176.  by an adjacent colon and equal sign character (:=).
  6177.  
  6178.  Examples of assignment statements:
  6179.  
  6180.       A := B
  6181.  
  6182.       A[I] := 12 * 4 + (B * C)
  6183.  
  6184.       X : = Y
  6185.       {Illegal. Colon (:) and equal}
  6186.       {sign (=) must be adjacent.}
  6187.  
  6188.       A + 2 := B
  6189.       {Illegal. A + 2 is not a variable.}
  6190.  
  6191.       A := ADD (1,1)
  6192.  
  6193.  The value of the expression must be assignment compatible with the type of
  6194.  the variable. Selection of the variable may involve indexing an array or
  6195.  dereferencing a pointer or address. If it does, the compiler may,
  6196.  depending on the optimizations performed, mix these actions with the
  6197.  evaluation of the expression. If the $simple metacommand is on, the
  6198.  expression is evaluated first.
  6199.  
  6200.  An assignment to a nonlocal variable (including a function return)
  6201.  puts an equal sign (=) or percent sign (%) in the G column of the listing
  6202.  file.  See Section 18.5, "Listing File Format," for more information about
  6203.  these and other symbols used in the listing.
  6204.  
  6205.  Within the block of a function, an assignment to the identifier of the
  6206.  function sets the value returned by the function. The assignment to a
  6207.  function identifier may occur either within the actual body of the function
  6208.  or in the body of a procedure or function nested within it.
  6209.  
  6210.  If the range checking switch is on, an assignment to a set, subrange,
  6211.  or LSTRING variable may imply a runtime call to the error checking code.
  6212.  
  6213.  According to the MS-Pascal optimizer, each section of code without
  6214.  a label or other point that could receive control is eligible for
  6215.  rearrangement and common subexpression elimination. Naturally, the order
  6216.  of execution is retained when necessary.
  6217.  
  6218.  Given these statements,
  6219.  
  6220.      X := A + C + B;
  6221.      Y := A + B;
  6222.      Z := A
  6223.  
  6224.  the compiler might generate code to perform the following operations:
  6225.  
  6226.      1.  Get the value of A and save it.
  6227.  
  6228.      2.  Add the value of B and save the result.
  6229.  
  6230.      3.  Add the value of C and assign it to X.
  6231.  
  6232.      4.  Assign the saved A + B value to Y.
  6233.  
  6234.      5.  Assign the saved A value to Z.
  6235.  
  6236.  This optimization occurs only if assignment to X and Y and getting the
  6237.  value of A, B, or C are all independent. If C is a function without the
  6238.  PURE attribute and A is a global variable, evaluating C might change A.
  6239.  Then since the order of evaluation within an expression in this case is not
  6240.  fixed, the value of A in the first assignment could be the old value or the
  6241.  new one.
  6242.  
  6243.  However, since the order of evaluation among statements is fixed, the
  6244.  value of A in the second and third assignments is the new value.
  6245.  
  6246.  The following actions may limit the ability of the optimizer to find
  6247.  common subexpressions:
  6248.  
  6249.      1.  assignment to a nonlocal variable
  6250.  
  6251.      2.  assignment to a reference parameter
  6252.  
  6253.      3.  assignment to the referent of a pointer
  6254.  
  6255.      4.  assignment to the referent of an address variable
  6256.  
  6257.      5.  calling a procedure
  6258.  
  6259.      6.  calling a function without the PURE attribute
  6260.  
  6261.  The optimizer does allow for "aliases," that is, a single variable with
  6262.  two identifiers, perhaps one as a global variable and one as a reference
  6263.  parameter.
  6264.  
  6265.  
  6266.  13.2.2  Procedure Statements
  6267.  
  6268.  
  6269.  A procedure statement executes the procedure denoted by the procedure
  6270.  identifier.
  6271.  
  6272.  For example, assume you have defined the procedure DO_IT:
  6273.  
  6274.       PROCEDURE DO_IT;
  6275.       BEGIN
  6276.         WRITELN('Did it')
  6277.       END;
  6278.  
  6279.  DO_IT is now a statement that can be executed simply by invoking its name:
  6280.  
  6281.       DO_IT
  6282.  
  6283.  If you declare the procedure with a formal parameter list, the
  6284.  procedure statement must include the actual parameters.
  6285.  
  6286.  MS-Pascal includes a large number of predeclared procedures. See
  6287.  Chapter 15, "Available Procedures and Functions," for complete information.
  6288.  One of the predeclared procedures is ASSIGN. You need not declare it in
  6289.  order to use it.
  6290.  
  6291.       ASSIGN (INFILE, 'MYFILE')
  6292.  
  6293.  Note that the ASSIGN procedure contains a parameter list. These
  6294.  parameters are the actual parameters that are bound to the formal
  6295.  parameters in the procedure declaration. For a discussion of formal and
  6296.  reference parameters, see Section 14.4, "Procedure and Function
  6297.  Parameters."
  6298.  
  6299.  
  6300.  13.2.3  The GOTO Statement
  6301.  
  6302.  
  6303.  A GOTO statement indicates that further processing continues at another
  6304.  part of the program text, namely at the place of the label. You must
  6305.  declare a LABEL in a LABEL declaration section, before using it in a GOTO
  6306.  statement.
  6307.  
  6308.  Several restrictions apply to the use of GOTO statements:
  6309.  
  6310.      1.  A GOTO must not jump to a more deeply nested statement, that is,
  6311.          into an IF, CASE, WHILE, REPEAT, FOR, or WITH statement. GOTOs
  6312.          from one branch of an IF or CASE statement to another are
  6313.          permitted.
  6314.  
  6315.      2.  A GOTO from one procedure or function to a label in the main
  6316.          program or in a higher level procedure or function is permitted. A
  6317.          GOTO may jump out of one of these statements, so long as the
  6318.          statement is directly within the body of the procedure or function.
  6319.          However, such a jump generates extra code both at the location of
  6320.          the GOTO and at the location of the label. The GOTO and label must
  6321.          be in the same compiland, since labels, unlike variables, cannot be
  6322.          given the PUBLIC attribute.
  6323.  
  6324.  Examples of GOTO statements, both legal and illegal:
  6325.  
  6326.       PROGRAM LABEL_EXAMPLES;
  6327.       LABEL 1, 2, 3, 4;
  6328.  
  6329.         PROCEDURE ONE;
  6330.         LABEL 11, 12, 13;
  6331.  
  6332.           PROCEDURE IN_ONE;
  6333.           LABEL 21;
  6334.           {Outer level GOTOs cannot jump in to 21.}
  6335.  
  6336.           BEGIN
  6337.             IF TUESDAY THEN GOTO 1
  6338.             ELSE GOTO 11;
  6339.             {1 and 11 are both legal outer level labels.}
  6340.             21 : WRITE ('IN_ONE')
  6341.           END;
  6342.  
  6343.         BEGIN   {Procedure one}
  6344.           IF RAINING THEN GOTO 1 ELSE GOTO 11;
  6345.           {This is legal.}
  6346.           11 : GOTO 21
  6347.           {Illegal. Cannot jump into inner level}
  6348.           {procedures.}
  6349.         END;
  6350.  
  6351.         PROCEDURE TWO;
  6352.         BEGIN
  6353.           GOTO 11
  6354.           {Illegal. Cannot jump into different procedure}
  6355.           {at same level.}
  6356.         END;
  6357.  
  6358.       BEGIN   {Main level}
  6359.         IF SEATTLE
  6360.         THEN
  6361.           BEGIN BEGIN
  6362.             GOTO 2;
  6363.             {OK to go to 2 at program level.}
  6364.             4 : WRITE ('here')
  6365.           END END
  6366.         ELSE GOTO 4;
  6367.         {OK to jump into THEN clause.}
  6368.         2 : GOTO 3;
  6369.         {Illegal. Cannot jump into REPEAT statement.}
  6370.         REPEAT
  6371.             WHILE MS_BYRON DO
  6372.               3 : GOTO 2
  6373.               {OK to jump out of loops.}
  6374.         UNTIL DATE;
  6375.         1 : GOTO 11
  6376.         {Illegal. Cannot jump into procedure from program.}
  6377.       END.
  6378.  
  6379.  If the $goto metacommand is on, every GOTO statement is flagged with a
  6380.  warning that reminds you that "GOTOs are considered harmful." This may be
  6381.  useful either in an educational environment or for finding all GOTOs in a
  6382.  program in order to locate a bug. The J (jumps) column of the listing file
  6383.  contains the following:
  6384.  
  6385.      1.  A plus (+) flags a GOTO to a label later in the listing.
  6386.  
  6387.      2.  A minus sign (-) marks a GOTO to a label already encountered in the
  6388.          listing.
  6389.  
  6390.      3.  An asterisk (*) flags a RETURN or a mixture of jumps.
  6391.  
  6392.  See Section 18.5, "Listing File Format," for details about the listing
  6393.  file.
  6394.  
  6395.  
  6396.  13.2.4  The BREAK, CYCLE, and RETURN Statements
  6397.  
  6398.  
  6399.  At the extend level, BREAK, CYCLE, and RETURN statements are allowed in
  6400.  addition to the simple statements already described. These statements
  6401.  perform the following functions:
  6402.  
  6403.      1.  BREAK exits the currently executing loop.
  6404.  
  6405.      2.  CYCLE exits the current iteration of a loop and starts the next
  6406.          iteration.
  6407.  
  6408.      3.  RETURN exits the current procedure, function, program, or
  6409.          implementation.
  6410.  
  6411.  All three statements are functionally equivalent to a GOTO
  6412.  statement.
  6413.  
  6414.      1.  A BREAK statement is a GOTO to the first statement after a
  6415.          repetitive statement.
  6416.  
  6417.      2.  A CYCLE statement is a GOTO to an implied empty statement after
  6418.          the body of a repetitive statement. This jump starts the next
  6419.          iteration of a loop. In either a WHILE or REPEAT statement, CYCLE
  6420.          performs the Boolean test in the WHILE or UNTIL clause before
  6421.          executing the statement again; in a FOR statement, CYCLE goes to
  6422.          the next value of the control variable.
  6423.  
  6424.      3.  A RETURN statement is a GOTO to an implied empty statement
  6425.          after the last statement in the current procedure or function
  6426.          or the body of a program or implementation.
  6427.  
  6428.  The J (jump) column in the listing file contains a plus sign (+) for a
  6429.  BREAK or GOTO statement, a minus sign (-) for a CYCLE or GOTO statement,
  6430.  and an asterisk  (*) for a RETURN statement or a mixture of jumps. See
  6431.  Section 18.5, "Listing File Format," for information about the listing
  6432.  file.
  6433.  
  6434.  BREAK and CYCLE have two forms, one with a loop label and one without.
  6435.  If you give a loop label, the label identifies the loop to exit or restart.
  6436.  If you don't give a label, the innermost loop is assumed, as shown in the
  6437.  following example:
  6438.  
  6439.       OUTER : FOR I := 1 TO N1 DO
  6440.         INNER : FOR J := 1 TO N2 DO
  6441.           IF A [I, J] = TARGET THEN BREAK OUTER;
  6442.  
  6443.  
  6444.  13.3  Structured Statements
  6445.  
  6446.  
  6447.  Structured statements are themselves composed of other statements.
  6448.  There are four kinds of structured statements:
  6449.  
  6450.      1.  compound statements
  6451.  
  6452.      2.  conditional statements
  6453.  
  6454.      3.  repetitive statements
  6455.  
  6456.      4.  WITH statements
  6457.  
  6458.  The control level is shown in the the C (control) column of the listing
  6459.  file. The value in the C column is incremented each time control passes to
  6460.  a nested statement; conversely, this value is decremented each time control
  6461.  passes back to the nesting statement. This helps you search for a missing
  6462.  or extra END in a program.
  6463.  
  6464.  
  6465.  13.3.1  Compound Statements
  6466.  
  6467.  
  6468.  The compound statement is a sequence of simple statements, enclosed by
  6469.  the reserved words BEGIN and END. The components of a compound statement
  6470.  execute in the same sequence as they appear in the source file.
  6471.  
  6472.  Examples of compound statements:
  6473.  
  6474.       BEGIN
  6475.          TEMP := A [I];
  6476.          A[I] := A [J];
  6477.          A [J] := TEMP
  6478.          {Semicolon not needed here.}
  6479.       END
  6480.  
  6481.       BEGIN
  6482.          OPEN_DOOR;
  6483.          LET_EM_IN;
  6484.          CLOSE_DOOR;
  6485.          {Semicolon signifies empty statement.}
  6486.       END
  6487.  
  6488.  All MS-Pascal conditional and repetitive control structures (except REPEAT)
  6489.  operate on a single statement, not on multiple statements with ending
  6490.  delimiters. In this context, BEGIN and END serve as punctuation, like
  6491.  semicolon, colon, or parentheses. If you prefer, you may substitute a pair
  6492.  of square brackets for the BEGIN and END pair of reserved words. Note
  6493.  that a right bracket (]) matches only a left bracket ([) (not a BEGIN,
  6494.  CASE, or RECORD). In other words, a right bracket is not a synonym for
  6495.  END.
  6496.  
  6497.  Brackets may not be used as synonyms for BEGIN and END to enclose the
  6498.  body of a program, implementation, procedure, or function; only BEGIN and
  6499.  END can be used for this purpose.
  6500.  
  6501.  Examples of brackets replacing BEGIN and END:
  6502.  
  6503.       IF FLAG THEN [X := 1; Y := -1]
  6504.       ELSE [X := -1; Y := 0];
  6505.  
  6506.       WHILE P.N <> NIL DO
  6507.          [Q := P;  P := P.N; DISPOSE (Q)];
  6508.  
  6509.       FUNCTION R2 (R : REAL) : REAL;
  6510.          [R2 := R * 2]
  6511.          {Illegal.}
  6512.  
  6513.  
  6514.  13.3.2  Conditional Statements
  6515.  
  6516.  
  6517.  A conditional statement selects for execution only one of its component
  6518.  statements. The conditional statements are the IF and CASE statements. Use
  6519.  the IF statement for one or two conditions, the CASE statement for multiple
  6520.  conditions.
  6521.  
  6522.  
  6523.  13.3.2.1  The IF Statement
  6524.  
  6525.  The IF statement allows for conditional execution of a statement. If
  6526.  the Boolean expression following the IF is true, the statement following
  6527.  the THEN is executed. If the Boolean expression following the IF is false,
  6528.  the statement following the ELSE, if present, is executed.
  6529.  
  6530.  Examples of IF statements:
  6531.  
  6532.       IF I > 0 THEN I := I - 1
  6533.       {No semicolon here.}
  6534.       ELSE I := I + 1
  6535.  
  6536.       IF (I <= TOP) AND (ARRI [I] <> TARGET) THEN
  6537.          I := I + 1
  6538.  
  6539.       IF I <= TOP THEN
  6540.          IF ARRI [I] <> TARGET THEN
  6541.             I := I + 1
  6542.  
  6543.       IF I = 1 THEN
  6544.          IF J = 1 THEN
  6545.             WRITELN('I equals J')
  6546.          ELSE
  6547.             WRITELN('DONE only if I = 1 and J <> 1')
  6548.             {This ELSE is paired with the most deeply}
  6549.             {nested IF.  Thus, the second WRITELN is}
  6550.             {executed only if I = 1 and J <> 1.}
  6551.  
  6552.       IF I = 1 THEN BEGIN
  6553.          IF J = 1 THEN WRITELN('I equals J')
  6554.          END
  6555.       ELSE
  6556.          WRITELN('DONE only if I <> 1')
  6557.            {Now the ELSE is paired with the first IF,}
  6558.            {since the second IF statement is}
  6559.            {bracketed by the BEGIN/END pair. Thus,}
  6560.            {the second WRITELN is executed if I <> 1.}
  6561.  
  6562.  A semicolon (;) preceding an ELSE is always incorrect. The compiler skips
  6563.  it during compilation and issues a warning message.
  6564.  
  6565.  The Boolean expression following an IF may include the sequential
  6566.  control operators described in Section 13.3.5, "Sequential Control," later
  6567.  in this chapter.
  6568.  
  6569.  
  6570.  13.3.2.2  The CASE Statement
  6571.  
  6572.  The CASE statement consists of an expression (called the CASE index)
  6573.  and a list of statements.  Each statement is preceded by a constant list,
  6574.  called a CASE constant list. The one statement executed is the one whose
  6575.  CASE constant list contains the current value of the CASE index. The CASE
  6576.  index and all constants must be of compatible, ordinal types.
  6577.  
  6578.  Examples of CASE statements:
  6579.  
  6580.       CASE OPERATOR OF
  6581.         PLUS : X := X + Y;
  6582.         MINUS : X := X - Y;
  6583.         TIMES: X := X * Y
  6584.       END
  6585.       {OPERATOR is the CASE index. PLUS, MINUS, and}
  6586.       {TIMES are CASE constants. In this instance,}
  6587.       {they are all of the values assumable by the}
  6588.       {enumerated variable, OPERATOR.}
  6589.  
  6590.       CASE NEXTCH OF
  6591.         'A'..'Z', '_' : IDENTIFIER;
  6592.         '+', '-', '*', '/' : OPERATOR;
  6593.         {Commas separate CASE constants}
  6594.         {and ranges of CASE constants.}
  6595.         OTHERWISE
  6596.           WRITE ('Unknown Character')
  6597.           {i.e., if any other character}
  6598.       END
  6599.  
  6600.  The CASE constant syntax is the same as for RECORD variant declarations.
  6601.  In standard Pascal, a CASE constant is one or more constants separated by
  6602.  commas. At the extend level, you may substitute a range of constants,
  6603.  such as 'A'..'Z', for a constant. No constant value can apply to more than
  6604.  one statement. The extend level also allows the CASE statement to end with
  6605.  an OTHERWISE clause. The OTHERWISE clause contains additional statements to
  6606.  be executed in the event that the CASE index value is not in the given
  6607.  set of CASE constant values. One of two things happens if the CASE index
  6608.  value is not in the set and no OTHERWISE clause is present:
  6609.  
  6610.      1.  If the range checking switch is on, a runtime error is generated.
  6611.  
  6612.      2.  If the range checking switch is off, the result is undefined (and
  6613.          may be catastrophic).
  6614.  
  6615.  In MS-Pascal, control does not automatically pass to the next
  6616.  executable statement as in UCSD Pascal and some other languages.
  6617.  If you want this effect, include an empty OTHERWISE clause.
  6618.  
  6619.  A semicolon (;) may appear after the final statement in the list, but
  6620.  is not required.  The compiler skips over a colon (:) after an OTHERWISE
  6621.  and issues a warning.
  6622.  
  6623.  Depending on optimization, the code generated by the compiler for a
  6624.  CASE statement may be either a "jump table" or series of comparisons (or
  6625.  both).  If it is a jump table, a jump to an arbitrary location in memory
  6626.  can occur if the control variable is out of range and the range checking
  6627.  switch is off.
  6628.  
  6629.  
  6630.  13.3.3  Repetition Statements
  6631.  
  6632.  
  6633.  Repetition statements specify repeated execution of a statement. In
  6634.  standard Pascal, these include the WHILE, REPEAT, and FOR statements.
  6635.  
  6636.  At the extend level in MS-Pascal, there are two additional statements,
  6637.  BREAK and CYCLE, for leaving or restarting the statements being repeated.
  6638.  These statements are functionally equivalent to a GOTO but easier to use.
  6639.  
  6640.  
  6641.  13.3.3.1  The WHILE Statement
  6642.  
  6643.  The WHILE statement repeats a statement zero or more times, until a
  6644.  Boolean expression becomes false.
  6645.  
  6646.  Examples of WHILE statements:
  6647.  
  6648.       WHILE P <> NIL DO P := NEXT (P)
  6649.  
  6650.       WHILE NOT MICKEY DO
  6651.          BEGIN
  6652.             NEXTMOUSE;
  6653.             MICE := MICE + 1
  6654.          END
  6655.  
  6656.  The Boolean expression in a WHILE statement may include the sequential
  6657.  control operators described in Section 13.3.5, "Sequential Control."
  6658.  
  6659.  Use WHILE if it is possible that no iterations of the loop may be
  6660.  necessary; use REPEAT where you expect that at least one iteration of the
  6661.  loop is required.
  6662.  
  6663.  
  6664.  13.3.3.2  The REPEAT Statement
  6665.  
  6666.  
  6667.  The REPEAT statement repeats a sequence of statements one or more
  6668.  times, until a Boolean expression becomes true.
  6669.  
  6670.  Examples of REPEAT statements:
  6671.  
  6672.       REPEAT
  6673.          READ (LINEBUFF);
  6674.          COUNT := COUNT + 1
  6675.       UNTIL EOF;
  6676.  
  6677.       REPEAT GAME UNTIL TIRED;
  6678.  
  6679.  
  6680.  The Boolean expression in a REPEAT statement may include the sequential
  6681.  control operators described in Section 13.3.5, "Sequential Control."
  6682.  
  6683.  Use the REPEAT statement to execute statements, not just a single
  6684.  statement, one or more times until a condition becomes true. This differs
  6685.  from the WHILE statement in which a single statement may not be executed at
  6686.  all.
  6687.  
  6688.  
  6689.  13.3.3.3  The FOR Statement
  6690.  
  6691.  The FOR statement tells the compiler to execute a statement repeatedly
  6692.  while a progression of values is assigned to a variable, called the control
  6693.  variable of the FOR statement. The values assigned start with a value
  6694.  called the initial value and end with one called the final value.
  6695.  
  6696.  The FOR statement has two forms, one where the control variable
  6697.  increases in value and one where the control variable decreases in value:
  6698.  
  6699.       FOR I := 1 TO 10 DO
  6700.       {I is the control variable.}
  6701.         SUM := SUM + VICTORVECTOR [I]
  6702.  
  6703.       FOR CH := 'Z' DOWNTO 'A' DO
  6704.       {CH is the control variable.}
  6705.         WRITE (CH)
  6706.  
  6707.  
  6708.  You may also use a FOR statement to step through the values of a set, as
  6709.  shown:
  6710.  
  6711.       FOR TINT :=
  6712.          LOWER (SHADES) TO UPPER (SHADES) DO
  6713.             IF TINT IN SHADES
  6714.             THEN PAINT_AREA (TINT);
  6715.  
  6716.  The ISO standard gives explicit rules regarding the control variable in FOR
  6717.  statements:
  6718.  
  6719.      1.  It must be of an ordinal type.
  6720.  
  6721.      2.  It must be an entire variable, not a component of a structure.
  6722.  
  6723.      3.  It must be local to the immediately enclosing program, procedure,
  6724.          or function and cannot be a reference parameter of the procedure or
  6725.          function.
  6726.  
  6727.          However, at the extend level of MS-Pascal, the control variable may
  6728.          also be any STATIC variable, such as a variable declared at the
  6729.          program level, unless the variable has a segmented ORIGIN
  6730.          attribute. Using a program level variable is an ISO error not
  6731.          caught.
  6732.  
  6733.      4.  No assignments to the control variable are allowed in the repeated
  6734.          statement. This error is caught by making the control variable
  6735.          READONLY within the FOR statement; it is not caught when a
  6736.          procedure or function invoked by the repeated statement alters the
  6737.          control variable. The control variable cannot be passed as a VAR
  6738.          (or VARS) parameter to a procedure or function.
  6739.  
  6740.      5.  The initial and final values of the control variable must be
  6741.          compatible with the type of the control variable. If the statement
  6742.          is executed, both the initial and final values must also be
  6743.          assignment compatible with the control variable. The initial value
  6744.          is always evaluated first, and then the final value. Both are
  6745.          evaluated only once before the statement executes.
  6746.  
  6747.  The statement following the DO is not executed at all if:
  6748.  
  6749.      1.  The initial value is greater than the final value in the TO case.
  6750.  
  6751.      2.  The initial value is less than the final value in the DOWNTO case.
  6752.  
  6753.  The sequence of values given the control variable starts with the initial
  6754.  value. This sequence is defined with the SUCC function for the TO case
  6755.  or the PRED function for the DOWNTO case until the last execution of
  6756.  the statement, when the control variable has its final value. The value of
  6757.  the control variable, after a FOR statement terminates naturally (whether
  6758.  or not the body executes), is undefined. It may vary due to optimization
  6759.  and, if $initck is on, may be set to an uninitialized value. However, the
  6760.  value of the control variable after leaving a FOR statement with GOTO or
  6761.  BREAK is defined as the value it had at the time of exit.
  6762.  
  6763.  In standard Pascal, the body of a FOR statement may or may not be
  6764.  executed, so a test is necessary to see whether the body should be executed
  6765.  at all.  However, if the control variable is of type WORD (or a subrange)
  6766.  and its initial value is a constant zero, the body must be executed no
  6767.  matter what the final value. In this case, no extra test need be executed
  6768.  and no code is generated to perform such a test.
  6769.  
  6770.  Also, a control variable with the STATIC attribute may be more
  6771.  efficient than one that is not.
  6772.  
  6773.  At the extend level in MS-Pascal, you may use temporary control
  6774.  variables:
  6775.  
  6776.       FOR VAR control-variable
  6777.  
  6778.  The prefix VAR causes the control variable to be declared local to
  6779.  the FOR statement (i.e., at a lower scope) and need not be declared in a
  6780.  VAR section. Such a control variable is not available outside the FOR
  6781.  statement, and any other variable with the same identifier is not available
  6782.  within the FOR statement itself. Other synonymous variables are, however,
  6783.  available to procedures or functions called within the FOR statement.
  6784.  
  6785.  Examples of temporary control variables:
  6786.  
  6787.       FOR VAR I := 1 TO 100 DO
  6788.          SUM := SUM + VICTOR [I]
  6789.  
  6790.       FOR VAR COUNTDOWN := 10 DOWNTO LIFT_OFF DO
  6791.          MONITOR_ROCKET
  6792.  
  6793.  
  6794.  
  6795.  13.3.3.4  The BREAK and CYCLE Statements
  6796.  
  6797.  In theory, a program using the MS-Pascal extend level BREAK and CYCLE
  6798.  statements does not need to use any GOTO statements.
  6799.  
  6800.  Each of these two statements has two forms, one with a loop label and
  6801.  one without. A loop label is a normal GOTO label prefixed to a FOR,
  6802.  WHILE, or REPEAT statement. Since, at the extend level, you may use
  6803.  identifier labels, a suggested practice is to use integers for labels
  6804.  referenced by GOTOs and identifiers for loop labels.
  6805.  
  6806.  Examples of CYCLE and BREAK statements:
  6807.  
  6808.       LABEL SEARCH, CLIMB;
  6809.         .
  6810.         .
  6811.       SEARCH : WHILE I <= I_TOP DO
  6812.         IF PILE [I] = TARGET THEN BREAK SEARCH
  6813.         ELSE I := I + 1;
  6814.         .
  6815.         .
  6816.       FOR I := 1 TO N DO
  6817.         IF NEXT [I] = NIL THEN BREAK;
  6818.         .
  6819.         .
  6820.       CLIMB : WHILE NOT ITEM^.LEAF DO
  6821.         BEGIN
  6822.           IF ITEM^.LEFT <> NIL
  6823.             THEN [ITEM := ITEM^.LEFT; CYCLE CLIMB];
  6824.           IF ITEM^.RIGHT <> NIL
  6825.             THEN [ITEM := ITEM^.RIGHT; CYCLE CLIMB];
  6826.           WRITELN ('Very strange node');
  6827.           BREAK CLIMB
  6828.         END;
  6829.  
  6830.  
  6831.  13.3.4  The WITH Statement
  6832.  
  6833.  
  6834.  The WITH statement opens the scope of a statement to include the fields
  6835.  of one or more records, so you can refer to the fields directly. For
  6836.  example, the following statements are equivalent:
  6837.  
  6838.      WITH PERSON DO WRITE (NAME, ADDRESS, PHONE)
  6839.      WRITE (PERSON.NAME, PERSON.ADDRESS, PERSON.PHONE)
  6840.  
  6841.  The record given may be a variable, constant identifier, structured
  6842.  constant, or function identifier; it may not be a component of a PACKED
  6843.  structure. If you use a function identifier, it refers to the function's
  6844.  local result variable. If the record given in a WITH statement is a file
  6845.  buffer variable, the compiler issues a warning, since changing the position
  6846.  in the WITH statement may cause an error.
  6847.  
  6848.  The record given can also be any expression in parentheses, in which
  6849.  case the expression is evaluated and the result assigned to a temporary
  6850.  (hidden) variable. If you want to evaluate a function designator, you must
  6851.  enclose it in parentheses.
  6852.  
  6853.  You may give a list of records after the WITH, separated by commas.
  6854.  Each record so listed must be of a different type from all the others,
  6855.  since the field identifiers refer only to the last instance of the record
  6856.  with the type. These statements are equivalent:
  6857.  
  6858.      WITH PMODE, QMODE DO statement
  6859.      WITH PMODE DO WITH QMODE DO statement
  6860.  
  6861.  Any record variable of a WITH statement that is a component of another
  6862.  variable is selected before the statement is executed. Active WITH
  6863.  variables should not be passed as VAR or VARS parameters, nor can their
  6864.  pointers be passed to the DISPOSE procedure. However, these errors are not
  6865.  caught by the compiler. Assignments to any of the record variables in the
  6866.  WITH list or components of these variables are allowed, as long as the WITH
  6867.  record is a variable.
  6868.  
  6869.  In MS-Pascal, every WITH statement allocates an address variable that
  6870.  holds the address of the record. If the record variable is on the heap, the
  6871.  pointer to it should not be DISPOSEd within the WITH statement. If the
  6872.  record variable is a file buffer, no I/O should be done to the file within
  6873.  the WITH statement. Avoid assignments to the WITH record itself in
  6874.  programs intended to be portable.
  6875.  
  6876.  
  6877.  13.3.5  Sequential Control
  6878.  
  6879.  
  6880.  To increase execution speed or guarantee correct evaluation, it is
  6881.  often useful in IF, WHILE, and REPEAT statements to treat the Boolean
  6882.  expression as a series of tests. If one test fails, the remaining tests are
  6883.  not executed. Two extend level operators in MS-Pascal provide for such
  6884.  tests:
  6885.  
  6886.      1.  AND THEN
  6887.  
  6888.         X AND THEN Y is false if X is false; Y is only evaluated if X
  6889.         is true.
  6890.  
  6891.      2.  OR ELSE
  6892.  
  6893.          X OR ELSE Y is true if X is true; Y is only evaluated if X is
  6894.          false.
  6895.  
  6896.  If you use several sequential control operators, the compiler evaluates
  6897.  them strictly from left to right.
  6898.  
  6899.  Examples of sequential control operators:
  6900.  
  6901.       IF SYM <> NIL AND THEN SYM^.VAL < 0 THEN
  6902.          NEXT_SYMBOL
  6903.       WHILE I <= MAX AND THEN VECT [I] <> KEY DO
  6904.          I := I + 1;
  6905.  
  6906.       REPEAT GEN (VAL)
  6907.       UNTIL VAL = 0 OR ELSE (QU DIV VAL) = 0;
  6908.  
  6909.       WHILE POOR AND THEN GETTING_POORER
  6910.          OR ELSE BROKE AND THEN BANKRUPT DO
  6911.             GET_RICH
  6912.  
  6913.  You may only include these operators in the Boolean expression of an IF,
  6914.  WHILE, or UNTIL clause; they may not be used in other Boolean expressions.
  6915.  Furthermore, they may not occur in parentheses and are evaluated after all
  6916.  other operators.
  6917.  
  6918.  
  6919.  
  6920.  Chapter 14  Introduction to Procedures and Functions
  6921.  
  6922.  ───────────────────────────────────────────────────────────────────────────
  6923.  
  6924.  14.1  Procedures
  6925.  
  6926.  14.2  Functions
  6927.  
  6928.  14.3  Attributes and Directives
  6929.  
  6930.         14.3.1  The FORWARD Directive
  6931.  
  6932.         14.3.2  The EXTERN  Directive
  6933.  
  6934.         14.3.3  The PUBLIC Attribute
  6935.  
  6936.         14.3.4  The ORIGIN Attribute
  6937.  
  6938.         14.3.5  The FORTRAN Attribute
  6939.  
  6940.         14.3.6  The INTERRUPT Attribute
  6941.  
  6942.         14.3.7  The PURE Attribute
  6943.  
  6944.  14.4  Procedure and Function Parameters
  6945.  
  6946.         14.4.1  Value Parameters
  6947.  
  6948.         14.4.2  Reference Parameters
  6949.  
  6950.                  14.4.2.1  Super Array Parameters
  6951.  
  6952.                  14.4.2.2  Constant and Segment Parameters
  6953.  
  6954.         14.4.3  Procedural and Functional Parameters
  6955.  
  6956.  
  6957.  
  6958.  Procedures and functions act as subprograms that execute under
  6959.  the supervision of a main program. Unlike programs, however, procedures and
  6960.  functions can be nested within each other and can even call themselves.
  6961.  Furthermore, they have sophisticated parameter passing capabilities that
  6962.  programs lack.
  6963.  
  6964.  Procedures are invoked as program statements; functions can be invoked
  6965.  in program statements wherever a value is called for.
  6966.  
  6967.  The general format for procedures and functions is similar to the
  6968.  format for programs. The three-part structure includes a heading,
  6969.  declarations, and a body.
  6970.  
  6971.  Example of a procedure declaration:
  6972.  
  6973.       {Heading}
  6974.       PROCEDURE MODEL (I : INTEGER; R : REAL);
  6975.  
  6976.       {Beginning of declaration section}
  6977.       LABEL 123;
  6978.       CONST ATOP = 199;
  6979.       TYPE INDEX = 0..ATOP;
  6980.       VAR ARAY : ARRAY [INDEX] OF REAL; J : INDEX;
  6981.       {Function declaration}
  6982.       FUNCTION FONE (RX : REAL) : REAL;
  6983.       BEGIN
  6984.          FONE := RX * I
  6985.       END;
  6986.  
  6987.       {Procedure declaration}
  6988.       PROCEDURE FOUT (RY : REAL);
  6989.       BEGIN
  6990.          WRITE ('Output is ', RY)
  6991.       END;
  6992.  
  6993.       {Body of procedure MODEL}
  6994.       BEGIN
  6995.         FOR J := 0 TO ATOP DO
  6996.           IF GLOBALVAR THEN
  6997.           {Activation of procedure FOUT with}
  6998.           {value returned by function FONE.}
  6999.                FOUT (FONE (R + ARAY [J]))
  7000.             ELSE GOTO 123;
  7001.         123:  WRITELN ('Done')
  7002.       END;
  7003.  
  7004.  The declarations and body together are called the block.
  7005.  
  7006.  The declaration of a procedure or function associates an identifier
  7007.  with a portion of a program. Later, you can activate that portion of the
  7008.  program with the appropriate procedure statement or function designator.
  7009.  
  7010.  
  7011.  14.1  Procedures
  7012.  
  7013.  
  7014.  The foregoing example illustrates the general format of a procedure
  7015.  declaration. The heading is followed by:
  7016.  
  7017.      1.  declarations for labels, constants, types, variables, and values
  7018.  
  7019.      2.  local procedures and functions
  7020.  
  7021.      3.  the body, which is enclosed by the reserved words BEGIN and END
  7022.  
  7023.  When the body of a procedure finishes execution, control returns to the
  7024.  program element that called it.
  7025.  
  7026.  At the standard level, the order of declarations must be as follows:
  7027.  
  7028.      1.  LABEL
  7029.  
  7030.      2.  CONST
  7031.  
  7032.      3.  TYPE
  7033.  
  7034.      4.  VAR
  7035.  
  7036.      5.  procedures and functions
  7037.  
  7038.  At the extend level, you may have any number of LABEL, CONST, TYPE,
  7039.  VAR, and VALUE sections, as well as procedure and function declarations, in
  7040.  any order.  Although data declarations (CONST, TYPE, VAR, VALUE) can be
  7041.  intermixed with procedure and function declarations, it is usually clearer
  7042.  to give all data declarations first.
  7043.  
  7044.  However, putting variable declarations after procedure and function
  7045.  declarations guarantees that these variables will not be used by any of the
  7046.  procedures or functions.
  7047.  
  7048.  In general, the initial values of variables are not defined.  The
  7049.  VALUE section, which should follow the VAR section, is an MS-Pascal
  7050.  extension that lets you explicitly initialize program, module,
  7051.  implementation, STATIC, and PUBLIC variables. If the initialization switch
  7052.  ($initck) is on, all INTEGER, INTEGER subrange, REAL, and pointer variables
  7053.  are set to an uninitialized value. File variables are always initialized,
  7054.  regardless of the setting of the initialization switch.
  7055.  
  7056.  
  7057.  14.2  Functions
  7058.  
  7059.  
  7060.  Functions are the same as procedures, except that they are invoked in
  7061.  an expression instead of a statement and they return a value.
  7062.  
  7063.  Function declarations define the parts of a program that compute a
  7064.  value. Functions are activated when a function designator, which is part of
  7065.  an expression, is evaluated.
  7066.  
  7067.  A function declaration has the same format as a procedure declaration,
  7068.  except that the heading also gives the type of value returned by the
  7069.  function.
  7070.  
  7071.  Example of a function heading:
  7072.  
  7073.       FUNCTION MAXIMUM (I, J : INTEGER) : INTEGER;
  7074.  
  7075.  Within the block of a function, either in the body itself or in a
  7076.  procedure or function nested within the block, at least one assignment to
  7077.  the function identifier must be executed to set the return value.  The
  7078.  compiler doesn't check for this assignment at runtime, unless the
  7079.  initialization switch is on and the returned type is INTEGER, REAL, or a
  7080.  pointer.  However, if there is no assignment at all to the function
  7081.  identifier, the compiler issues an error message.
  7082.  
  7083.  At the standard level, functions can return any simple type (ordinal,
  7084.  REAL, or INTEGER4) or a pointer.  At the extend level, functions can return
  7085.  any simple, structured, or reference type. However, they cannot return any
  7086.  type that cannot be assigned (i.e., a super array type or a structure
  7087.  containing a file, although a super array derived type is permitted).
  7088.  
  7089.  A function identifier in an expression invokes the function
  7090.  recursively, rather than giving the current value of the function.
  7091.  
  7092.  To obtain the current value, use the function RESULT, which takes the
  7093.  function identifier as a parameter and is available at the extend level.
  7094.  
  7095.  The following is an example of a RESULT function used to obtain the
  7096.  current value of a function within an expression:
  7097.  
  7098.      FUNCTION FACT (F : REAL) : REAL;
  7099.      BEGIN
  7100.        FACT := 1;
  7101.        WHILE F > 1 DO
  7102.           BEGIN
  7103.             FACT := RESULT (FACT) * F; F:= F - 1
  7104.           END
  7105.      END;
  7106.  
  7107.  Using the RESULT function is more efficient than using a separate
  7108.  local variable for the value of the function and then assigning this local
  7109.  variable to the function identifier before returning.  If the function has
  7110.  a structured value, the usual component selection syntax can follow the
  7111.  RESULT function.
  7112.  
  7113.  A function identifier on the left side of an assignment refers to the
  7114.  function's local variable, which contains its current value, instead of
  7115.  invoking the function recursively. Other places where using the function
  7116.  identifier refers to this local variable are the following:
  7117.  
  7118.      1.  a reference parameter
  7119.  
  7120.      2.  the record of a WITH statement
  7121.  
  7122.      3.  the operand of an ADR or ADS operator
  7123.  
  7124.  All of these uses involve getting the address (not the value) of a
  7125.  variable.
  7126.  
  7127.  Instead of using the function's local variable, you may want to invoke
  7128.  the function and use the return value. As mentioned in Section 11.1, "What
  7129.  Is a Variable?" getting the address of an expression involves evaluating
  7130.  the expression, putting the resulting value into a temporary (hidden)
  7131.  variable, and using the address of this variable.
  7132.  
  7133.  To do this for a function, you must force evaluation by putting the
  7134.  function designator in parentheses, as shown:
  7135.  
  7136.      TYPE IREC = RECORD I : INTEGER END;
  7137.  
  7138.      FUNCTION SUM (A, B : INTEGER) : IREC;
  7139.      {Return sum of A and B.}
  7140.      BEGIN
  7141.        IF TUESDAY THEN
  7142.        BEGIN                 {On Tuesdays, we recurse!}
  7143.          IF B = 0 THEN BEGIN SUM := A; RETURN END;
  7144.          WITH (SUM (A, B - 1))  {Call SUM recursively.}
  7145.            DO SUM.I := I + 1 {I is result of call.}
  7146.        END
  7147.        ELSE                  {Use function's}
  7148.          WITH SUM            {local variable.}
  7149.            DO I := A + B    {I is local variable.}
  7150.      END;
  7151.  
  7152.  
  7153.  14.3  Attributes and Directives
  7154.  
  7155.  
  7156.  An attribute gives additional information about a procedure or
  7157.  function. Attributes are available at the extend level of Microsoft
  7158.  Pascal. They are placed after the heading, enclosed in brackets, and
  7159.  separated by commas. Available attributes include ORIGIN, PUBLIC, FORTRAN,
  7160.  PURE, and INTERRUPT.
  7161.  
  7162.  A directive gives information about a procedure or function, but it
  7163.  also indicates that only the heading of the procedure or function occurs,
  7164.  by replacing the block (declarations and body) normally included after the
  7165.  heading. Directives are available in standard Pascal. EXTERN and FORWARD
  7166.  are the only directives available. EXTERN can only be used with procedures
  7167.  or functions directly nested in a program, module, implementation, or
  7168.  interface. This restriction prevents access to nonlocal stack variables.
  7169.  
  7170.  Table 14.1 displays the attributes and directives that apply to
  7171.  procedures and functions. Sections 14.3.1 through 14.3.7 describe these
  7172.  attributes and directives in detail.
  7173.  
  7174.  
  7175.  Table 14.1
  7176.  Attributes and Directives for Procedures and Functions
  7177. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  7178.  Name           Purpose
  7179.  ───────────────────────────────────────────────────────────────────────────
  7180.  FORWARD        A directive. Lets you call a procedure or function before
  7181.                 you give its block in the source file.
  7182.  
  7183.  EXTERN         A directive. Indicates that a procedure or function resides
  7184.  Name           Purpose
  7185. EXTERN         A directive. Indicates that a procedure or function resides
  7186.                 in another loaded module.
  7187.  
  7188.  PUBLIC         An attribute. Indicates that a procedure or function may
  7189.                 be accessed by other loaded modules.
  7190.  
  7191.  ORIGIN         An attribute. Tells the compiler where the code for an
  7192.                 EXTERN procedure or function resides.
  7193.  
  7194.  FORTRAN        An attribute. Specifies a calling sequence for compatibility
  7195.                 with Microsoft FORTRAN.
  7196.  
  7197.  INTERRUPT      An attribute. Gives a procedure a special calling sequence
  7198.                 that saves program status on the stack.
  7199.  
  7200.  PURE           An attribute. Signifies that the function does not modify
  7201.                 any global variables.
  7202.  
  7203.  The following rules apply when you combine attributes in the declaration of
  7204.  procedures and functions:
  7205.  
  7206.      1.  Any function may be given the PURE attribute.
  7207.  
  7208.      2.  Procedures and functions with attributes must be nested directly
  7209.          within a program, module, or unit. The only exception to this rule
  7210.          is the PURE attribute.
  7211.  
  7212.      3.  A given procedure or function may have only one calling sequence
  7213.          attribute (i.e., either FORTRAN or INTERRUPT, but not both).
  7214.  
  7215.      4.  PUBLIC and EXTERN are mutually exclusive, as are PUBLIC and ORIGIN.
  7216.  
  7217.  The EXTERN or FORWARD directive is given automatically to all
  7218.  constituents of the interface of a unit; in the implementation, PUBLIC is
  7219.  given automatically to all constituents that are not EXTERN.
  7220.  
  7221.  Since you declare the constituents of a unit only in the interface
  7222.  (not in the implementation), the interface is where you give the
  7223.  attributes.  You may give the EXTERN directive in an implementation by
  7224.  declaring all EXTERN procedures and functions first; you may not use ORIGIN
  7225.  in either the interface or implementation of a unit.
  7226.  
  7227.  In a module, you may give a group of attributes in the heading to
  7228.  apply to all directly nested procedures and functions.  The only exception
  7229.  to this rule is the ORIGIN attribute, which may apply only to a single
  7230.  procedure or function.
  7231.  
  7232.  If the PUBLIC attribute is one of a group of attributes in the heading
  7233.  of a module, an EXTERN attribute given to a procedure or function within
  7234.  the module explicitly overrides the global PUBLIC attribute. If the module
  7235.  heading has no attribute clause, the PUBLIC attribute is assumed for all
  7236.  directly nested procedures and functions.
  7237.  
  7238.  The PUBLIC attribute allows a procedure or function to be called by
  7239.  other loaded code, and cannot be used with the EXTERN directive. The
  7240.  EXTERN directive  permits a call to some other loaded code, using either
  7241.  the ORIGIN address or the linker. PUBLIC, EXTERN, and ORIGIN provide a low
  7242.  level way to link MS-Pascal routines with other routines in MS-Pascal or
  7243.  other languages.
  7244.  
  7245.  A procedure or function declaration with the EXTERN or FORWARD directive
  7246.  consists only of the heading, without an enclosed block. EXTERN
  7247.  routines have an implied block outside of the program. FORWARD routines are
  7248.  fully declared (have a block) later in the same compiland. Both directives
  7249.  are available at the standard level of MS-Pascal. The keyword EXTERNAL is
  7250.  a synonym for EXTERN.
  7251.  
  7252.  The PURE attribute applies only to functions, not to procedures.Conversely,
  7253.  INTERRUPT applies only to procedures, not to functions. PURE is the only
  7254.  attribute that can be used in nested functions.
  7255.  
  7256.  
  7257.  14.3.1  The FORWARD Directive
  7258.  
  7259.  
  7260.  A FORWARD declaration allows you to call a procedure or function before
  7261.  you fully declare it in the source text. This permits indirect recursion,
  7262.  where A calls B and B calls A. You make a FORWARD declaration by
  7263.  specifying a procedure or function heading, followed by the directive
  7264.  FORWARD. Later, you actually declare the procedure or function,
  7265.  without repeating the formal parameter list, attributes, or return types.
  7266.  
  7267.  Example of a FORWARD declaration:
  7268.  
  7269.       {Declaration of ALPHA, with parameter}
  7270.       {list and attributes}
  7271.       FUNCTION ALPHA (Q, R : REAL) : REAL [PUBLIC];
  7272.       FORWARD;
  7273.  
  7274.       {Call for ALPHA}
  7275.       PROCEDURE BETA (VAR S, T : REAL);
  7276.       BEGIN
  7277.         T := ALPHA (S, 3.14)
  7278.       END;
  7279.  
  7280.       {Actual declaration of ALPHA,}
  7281.       {without parameter list}
  7282.       FUNCTION ALPHA;
  7283.       BEGIN
  7284.         ALPHA := (Q + R);
  7285.         IF R < 0.0 THEN BETA (3.14, ALPHA)
  7286.       END;
  7287.  
  7288.  
  7289.  14.3.2  The EXTERN Directive
  7290.  
  7291.  
  7292.  The EXTERN directive identifies a procedure or function that resides in
  7293.  another loaded module. You give only the heading of the procedure or
  7294.  function, followed by the word EXTERN. The actual implementation of the
  7295.  procedure or function is presumed to exist in some other module.
  7296.  
  7297.  EXTERN is an attribute when used with a variable, but a directive when
  7298.  used with a procedure or function. As with variables, the keyword EXTERNAL
  7299.  is a synonym for EXTERN.
  7300.  
  7301.  The EXTERN directive for a particular procedure or function within a
  7302.  module overrides the PUBLIC attribute given for the entire module. The
  7303.  EXTERN directive is also permitted in an implementation of a unit for a
  7304.  constituent procedure or function. All such external constituents must be
  7305.  declared at the beginning of the implementation, before all other
  7306.  procedures and functions.
  7307.  
  7308.  Any procedure or function with the EXTERN directive must be directly
  7309.  nested within a program. You can also link MS-Pascal routines by linking
  7310.  separately compiled units. See Chapter 17, "Compilable Parts of a Program."
  7311.  
  7312.  Examples of procedure and function headings declared with the EXTERN
  7313.  directive:
  7314.  
  7315.       FUNCTION POWER (X, Y : REAL) : REAL; EXTERN;
  7316.  
  7317.       PROCEDURE ACCESS (KEY : KTYP) [ORIGIN SYSB + 4];
  7318.       EXTERN;
  7319.  
  7320.  In these examples, the function POWER is declared EXTERN, as is the
  7321.  procedure ACCESS. Both are implemented in external compilands. ACCESS also
  7322.  has the ORIGIN attribute, which is discussed later, in Section 14.3.4, "The
  7323.  ORIGIN Attribute."
  7324.  
  7325.  You may not declare a procedure or function EXTERN if you have previously
  7326.  declared it FORWARD.
  7327.  
  7328.  
  7329.  14.3.3  The PUBLIC Attribute
  7330.  
  7331.  
  7332.  The PUBLIC attribute indicates a procedure or function that you can
  7333.  access from other loaded modules. In general, you access PUBLIC procedures
  7334.  and functions from other loaded modules by declaring them EXTERN in the
  7335.  modules that call them. Thus, you declare a procedure PUBLIC and
  7336.  define it in one module, and use it in another simply by declaring it
  7337.  EXTERN in the other module.
  7338.  
  7339.  As with variables, the identifier of the procedure or function is
  7340.  passed to the linker, where it may be truncated if the linker requires it.
  7341.  See Appendix B, "Version Specifics," in your Microsoft Pascal Compiler
  7342.  User's Guide for specific information on limitations your version of the
  7343.  compiler and linker may set on identifiers. PUBLIC and ORIGIN are mutually
  7344.  exclusive; PUBLIC routines need a following block, and ORIGIN routines must
  7345.  be EXTERN.
  7346.  
  7347.  Any procedure or function with the PUBLIC attribute must be directly
  7348.  nested within a program or implementation. A higher level way to link MS-
  7349.  Pascal routines is by linking separately compiled units. See Chapter 17,
  7350.  "Compilable Parts of a Program," for details.
  7351.  
  7352.  Examples of procedures and functions declared PUBLIC:
  7353.  
  7354.       FUNCTION POWER (X, Y : REAL) : REAL [PUBLIC];
  7355.       {The function POWER is available to other modules}
  7356.       {because it has been declared PUBLIC.}
  7357.       BEGIN
  7358.         .
  7359.         .
  7360.       END;
  7361.  
  7362.       PROCEDURE ACCESS (KEY : KTYP)
  7363.       [ORIGIN SYSB + 4, PUBLIC];
  7364.       BEGIN
  7365.         .
  7366.         .
  7367.       END;
  7368.       {Illegal since ORIGIN must also be EXTERN.}
  7369.  
  7370.  
  7371.  14.3.4  The ORIGIN Attribute
  7372.  
  7373.  
  7374.  The ORIGIN attribute must be used with the EXTERN directive; ORIGIN tells
  7375.  the compiler where the procedure or function can be found directly, so
  7376.  the linker does not require a corresponding PUBLIC identifier.
  7377.  
  7378.  Examples of procedures and functions given the ORIGIN attribute:
  7379.  
  7380.       PROCEDURE OPSYS [ORIGIN 8, FORTRAN];
  7381.       EXTERN;
  7382.  
  7383.       FUNCTION A_TO_D (C : SINT) : SINT [ORIGIN #100];
  7384.       EXTERN;
  7385.  
  7386.  
  7387.  In the first example, the procedure OPSYS begins at the absolute
  7388.  decimal address 8, has the FORTRAN calling sequence (described in Section
  7389.  14.3.5, "The FORTRAN Attribute"), and is declared EXTERN. In the second
  7390.  example, the function A_TO_D takes a SINT value as a parameter (SINT is the
  7391.  predeclared integer subrange from -127 to +127). The function is located
  7392.  at the hexadecimal address 100.
  7393.  
  7394.  As with ORIGIN variables, the compiler uses the address to find the
  7395.  code and gives no directives to the linker. This permits, for example,
  7396.  calling routines at fixed addresses in ROM. In simple cases, it can
  7397.  substitute for a linking loader.
  7398.  
  7399.  Remember that ORIGIN always implies EXTERN. Thus, procedures or
  7400.  functions that have previously been declared FORWARD cannot be declared
  7401.  with the ORIGIN attribute. Nor may you give ORIGIN as an attribute after
  7402.  the module heading.
  7403.  
  7404.  Currently, you may not use the ORIGIN attribute with a constituent of
  7405.  a unit, either in an interface or in an implementation.
  7406.  
  7407.  As with variables, the origin can be a segmented address. On
  7408.  segmented machines, a nonsegmented procedural origin assumes the current
  7409.  code segment with the offset given with the attribute.
  7410.  
  7411.  
  7412.  14.3.5  The FORTRAN Attribute
  7413.  
  7414.  
  7415.  The FORTRAN attribute applies both to procedures and functions (but not
  7416.  to variables).  Instead of the usual Pascal calling sequence, it specifies
  7417.  a calling sequence that is compatible with the MS-FORTRAN compiler on your
  7418.  machine.  This lets you call an MS-Pascal procedure or function from
  7419.  MS-FORTRAN programs and, conversely, external FORTRAN subroutines or
  7420.  MS-FORTRAN functions from an MS-Pascal program.
  7421.  
  7422.  Example of a procedure with the FORTRAN attribute:
  7423.  
  7424.       PROCEDURE DELTA (I, J : INTEGER) [FORTRAN];
  7425.       FORWARD;
  7426.  
  7427.  Any procedure or function with the FORTRAN attribute must be nested
  7428.  directly within a program or implementation.
  7429.  
  7430.  In a 16-bit environment, MS-Pascal uses the same calling sequence as
  7431.  the compilers for Microsoft FORTRAN, Microsoft BASIC, and Microsoft COBOL.
  7432.  Thus, there is no need to give the FORTRAN attribute; if you do, it is
  7433.  ignored by the MS-Pascal Compiler.  See Appendix B, "Version Specifics," in
  7434.  your Microsoft Pascal Compiler User's Guide for details on the MS-Pascal
  7435.  calling sequence.
  7436.  
  7437.  
  7438.  14.3.6  The INTERRUPT Attribute
  7439.  
  7440.  
  7441.  The INTERRUPT attribute applies only to procedures (not to functions or
  7442.  variables). It gives a procedure a special calling sequence that saves
  7443.  program status on the stack, which in turn allows a hardware interrupt to
  7444.  be processed, status restored, and control returned to the program, all
  7445.  without affecting the current state of the program.
  7446.  
  7447.  Example of a procedure with the INTERRUPT attribute:
  7448.  
  7449.       PROCEDURE INCHAR [INTERRUPT];
  7450.  
  7451.  Because procedures with the INTERRUPT attribute are intended to be
  7452.  invoked by hardware interrupts, you may not invoke them with a procedure
  7453.  statement. An INTERRUPT procedure can only be invoked when the interrupt
  7454.  associated with it occurs. Furthermore, INTERRUPT procedures take no
  7455.  parameters.
  7456.  
  7457.  Declaring a procedure with the INTERRUPT attribute ensures that the
  7458.  procedure conforms to the constraints of an interrupt handler in which:
  7459.  
  7460.      1.  a special calling sequence saves all status on the stack
  7461.  
  7462.      2.  the status saved includes machine registers and flags, plus any
  7463.          special global compiler data such as the frame pointer
  7464.  
  7465.      3.  the saved status is restored upon exit from the procedure
  7466.  
  7467.  All INTERRUPT procedures must be nested directly within a compiland.
  7468.  
  7469.  Interrupts are not automatically vectored to INTERRUPT procedures;
  7470.  further, insofar as possible on the target machine, interrupts are neither
  7471.  enabled or disabled by an INTERRUPT procedure. Interrupt vectoring and
  7472.  enabling are too machine-dependent to be included in a machine-independent
  7473.  language like MS-Pascal.
  7474.  
  7475.  However, MS-Pascal does provide the VECTIN library procedure, which
  7476.  takes an interrupt level and an interrupt procedure as parameters and
  7477.  sets the interrupt vector in a machine-dependent way.
  7478.  
  7479.  Similarly,  the library procedures ENABIN and DISBIN, respectively,
  7480.  enable and disable interrupts in a machine-dependent way. See Chapter 15,
  7481.  " Available Procedures and Functions," for more information on these
  7482.  routines. See also Appendix B, "Version Specifics," in the Microsoft Pascal
  7483.  Compiler User's Guide for information about the implementation of these
  7484.  routines under your operating system.
  7485.  
  7486.  An INTERRUPT procedure should usually return normally, in order to
  7487.  continue processing in the interrupted routine. This means the following:
  7488.  
  7489.      1.  You should not execute a GOTO that leaves an INTERRUPT procedure.
  7490.  
  7491.      2.  All debug checking should be turned off ($debug-, $entry-, and
  7492.          $runtime-).
  7493.  
  7494.      3.  Stack overflow may not be checked even if $stackck is on.
  7495.  
  7496.  The use of INTERRUPT procedures introduces re-entrancy into MS-Pascal
  7497.  code: generated code is re-entrant, as is the runtime system (except for
  7498.  the heap unit and, in most operating systems, portions of the file unit).
  7499.  
  7500.  Some critical sections in the runtime system are protected by
  7501.  semaphores that generate a runtime error if such a critical section is
  7502.  locked.  For example, if the heap allocator is executing when an interrupt
  7503.  occurs and the INTERRUPT procedure tries to allocate a block from the heap,
  7504.  the structure of the heap could become invalid. This condition causes a
  7505.  runtime error.
  7506.  
  7507.  However, in most cases, the file system is not protected by a
  7508.  semaphore. Therefore, it is safest to avoid performing any I/O within the
  7509.  INTERRUPT procedure. Alternatively, you can avoid most problems with I/O in
  7510.  an INTERRUPT procedure by not opening or closing any files (i.e., not
  7511.  declaring any local file variables or creating files on the heap) and by
  7512.  not performing input or output with any file that might be in the process
  7513.  of performing I/O when the interrupt occurs.
  7514.  
  7515.  
  7516.  14.3.7  The PURE Attribute
  7517.  
  7518.  
  7519.  The PURE attribute applies only to functions, not to procedures or
  7520.  variables. PURE indicates to the compiler's optimizer that the function
  7521.  does not modify any global variables either directly or by calling some
  7522.  other procedure or function.
  7523.  
  7524.  Example of a PURE declaration:
  7525.  
  7526.       FUNCTION AVERAGE (CONST TABLE : RVECTOR):
  7527.       REAL [PURE];
  7528.  
  7529.  For further illustration, examine these statements:
  7530.  
  7531.       A := VEC [I * 10 + 7];
  7532.       B := FOO;
  7533.       C := VEC [I * 10 + 9];
  7534.  
  7535.  If the function FOO is given the PURE attribute, the optimizer only
  7536.  generates code to compute I * 10 once. However, FOO, if it is not declared
  7537.  PURE, may modify I so that I * 10 must be recomputed after the call to FOO.
  7538.  
  7539.  Functions are not considered PURE unless given the attribute explicitly
  7540.  The compiler checks to see that a PURE function does not do any of the
  7541.  following:
  7542.  
  7543.      1.  assign to a nonlocal variable
  7544.  
  7545.      2.  have any VAR or VARS parameters (CONST and CONSTS parameters are
  7546.          permitted)
  7547.  
  7548.      3.  call any functions that are not PURE
  7549.  
  7550.  Although the following additional restrictions are not checked, a PURE
  7551.  function should also:
  7552.  
  7553.      1.  not use the value of a global variable
  7554.  
  7555.      2.  not modify the referents of references passed by a value (e.g.,
  7556.          pointer or address type referents)
  7557.  
  7558.      3.  not do input or output
  7559.  
  7560.  Since the result of a PURE function with the same parameters must
  7561.  always be the same, the entire function call may be optimized away.  For
  7562.  example, if in the following statements DSIN is PURE; the compiler only
  7563.  calls DSIN once:
  7564.  
  7565.       HX := A * DSIN (P[I, J] * 2);
  7566.       HY := B * DSIN (P[I, J] * 2);
  7567.  
  7568.  
  7569.  14.4  Procedure and Function Parameters
  7570.  
  7571.  
  7572.  Procedures and functions may take three different types of parameters:
  7573.  
  7574.      1.  value parameters
  7575.  
  7576.      2.  reference parameters
  7577.  
  7578.      3.  procedural and functional parameters
  7579.  
  7580.  Each of these is discussed separately, in the order listed, in the
  7581.  following sections.
  7582.  
  7583.  The discussion mentions both formal and actual parameters. A formal
  7584.  parameter is the parameter given when the procedure or function is
  7585.  declared, with an identifier in the heading. When the function or
  7586.  procedure is called, an actual parameter substitutes for the formal
  7587.  parameter given earlier; here the parameter takes the form of a variable or
  7588.  value or expression.
  7589.  
  7590.  MS-Pascal has several parameter features at the extend level:
  7591.  
  7592.      1.  A super array type can be passed as a reference parameter.
  7593.  
  7594.      2.  A reference parameter can be declared READONLY.
  7595.  
  7596.      3.  Explicit segmented reference parameters can be declared.
  7597.  
  7598.  
  7599.  14.4.1  Value Parameters
  7600.  
  7601.  
  7602.  When a value parameter is passed, the actual parameter is an
  7603.  expression. That expression is evaluated in the scope of the calling
  7604.  procedure or function and assigned to the formal parameter. The formal
  7605.  parameter is a variable local to the procedure or function called.  Thus,
  7606.  formal value parameters are always local to a procedure or function.
  7607.  
  7608.  Example of value parameters:
  7609.  
  7610.      {Function declaration}
  7611.      FUNCTION ADD (A, B, C : REAL) : REAL;
  7612.         {A, B, and C are formal parameters}
  7613.        .
  7614.        .
  7615.      X := ADD (Y, ADD (1.111, 2.222, 3.333), (Z * 4))
  7616.  
  7617.  In this particular function invocation, Y, ADD(...), and (Z * 4) are
  7618.  the expressions that make up the actual parameters.  In this example, these
  7619.  expressions must all evaluate to the type REAL. (The example also
  7620.  recursively calls the function ADD.)
  7621.  
  7622.  The actual parameter expression must be assignment compatible with
  7623.  the type of the formal parameter.
  7624.  
  7625.  Passing structured types by value is permitted; however, it is
  7626.  inefficient, since the entire structure must be copied. A value parameter
  7627.  of a SET, LSTRING, or subrange type may also require a runtime error check
  7628.  if the range checking switch is on. In addition, SET and LSTRING value
  7629.  parameters may require extra generated code for size adjustment.
  7630.  
  7631.  A file variable or super array variable cannot be passed as a value
  7632.  parameter, since it cannot be assigned. However, a variable with a type
  7633.  derived from a super array or file buffer variable can be passed. Passing a
  7634.  file buffer variable as a value parameter implies normal evaluation of the
  7635.  buffer variable.
  7636.  
  7637.  
  7638.  14.4.2  Reference Parameters
  7639.  
  7640.  
  7641.  When a reference parameter is passed at the standard level of MS-
  7642.  Pascal, the keyword VAR precedes the formal parameter. Furthermore, the
  7643.  actual parameter must be a variable, not an expression.  The formal
  7644.  parameter denotes this actual variable during the execution of the
  7645.  procedure. Any operation on the formal parameter is performed immediately
  7646.  on the actual parameter, by passing the machine address of the actual
  7647.  variable to the procedure. For target processors with segmentation support,
  7648.  this address is an offset into the default data segment.
  7649.  
  7650.  Example of variable parameters:
  7651.  
  7652.      PROCEDURE CHANGE_VARS (VAR A, B, C : INTEGER);
  7653.      {A, B, and C are formal reference parameters.}
  7654.      {They denote variables, not values.}
  7655.        .
  7656.        .
  7657.      CHANGE_VARS (X, Y, Z);
  7658.  
  7659.  In this example, X, Y, and Z must be variables, not expressions.
  7660.  Also, the variables X, Y, and Z are altered whenever the formal parameters
  7661.  A, B, and C are altered in the declared procedure. This differs from the
  7662.  handling of value parameters, which can affect only the copies of values of
  7663.  variables.  If the selection of the variable involves indexing an array or
  7664.  dereferencing a pointer or address, these actions are executed before the
  7665.  procedure itself. The type of the actual parameter must be identical to the
  7666.  type of the formal parameter.
  7667.  
  7668.  Passing a nonlocal variable as a VAR parameter puts a slash (/) or
  7669.  percent sign (%) in the G (global) column of the listing file (see Section
  7670.  18.5, "Listing File Format," for information about the significance of
  7671.  these characters in the G column of the listing).
  7672.  
  7673.  None of the following may be passed as VAR parameters:
  7674.  
  7675.      1.  a component of a PACKED structure (except CHAR of a STRING or
  7676.          LSTRING)
  7677.  
  7678.      2.  any variable with a READONLY or PORT attribute (includes CONST and
  7679.          CONSTS parameters and the FOR control variable)
  7680.  
  7681.  Passing a file buffer variable by reference generates a warning
  7682.  message, because it bypasses the normal file system call generated by the
  7683.  use of any buffer variable. These calls are not generated when a file
  7684.  variable is passed by reference.
  7685.  
  7686.  On a segmented machine, a VAR parameter passes an address that is
  7687.  really an offset into a default data segment. In some cases, access to
  7688.  objects residing in other segments is required. To pass these objects by
  7689.  reference, you must tell the compiler to use a segmented address containing
  7690.  both segment register and offset values. The extend level includes the
  7691.  parameter prefix VARS instead of VAR:
  7692.  
  7693.       PROCEDURE CONCATS (VARS T, S : STRING);
  7694.  
  7695.  You may only use VARS as a data parameter in procedures and functions,
  7696.  not in the declaration section of programs, procedures, and functions.
  7697.  VARS and CONSTS parameters are provided chiefly to maintain compatibility
  7698.  with machines that have two different size address spaces. These
  7699.  parameters are not necessary for a machine with a single size address
  7700.  space. On such machines, the reserved words VARS and CONSTS are equivalent
  7701.  to VAR and CONST.
  7702.  
  7703.  
  7704.  14.4.2.1  Super Array Parameters
  7705.  
  7706.  Super array parameters may appear as formal reference parameters.  This
  7707.  allows a procedure or function to operate on an array with a particular
  7708.  super array type (also a component type and index type), but without any
  7709.  fixed upper bounds.  The formal parameter is a reference parameter of the
  7710.  super array type itself.
  7711.  
  7712.  The actual parameter type must be a type derived from the super array
  7713.  type or the super array type itself (i.e., another reference parameter or
  7714.  dereferenced pointer). Except for comparing LSTRINGs, super array type
  7715.  parameters cannot be assigned or compared as a whole.
  7716.  
  7717.  The actual upper and lower bounds of the array are available with the
  7718.  UPPER and LOWER functions; this permits routines that can operate on arrays
  7719.  of any size. An LSTRING actual parameter can be passed to a reference
  7720.  parameter of the super array type STRING. Therefore, the super array
  7721.  parameter STRING can be used for procedures and functions that operate on
  7722.  strings of both STRING and LSTRING types.
  7723.  
  7724.  Example of super array parameters:
  7725.  
  7726.       TYPE REALS = ARRAY [0..*] OF REAL;
  7727.  
  7728.       PROCEDURE SUMRS (VAR X : REALS; CONST X : REALS);
  7729.       BEGIN
  7730.         .
  7731.         .
  7732.       END;
  7733.  
  7734.  For more information, see the following sections of this manual:
  7735.  
  7736.  Section 7.2, "Super Arrays"
  7737.  
  7738.  Section 7.2.1, "STRINGs"
  7739.  
  7740.  Section 7.2.2, "LSTRINGs"
  7741.  
  7742.  
  7743.  14.4.2.2  Constant and Segment Parameters
  7744.  
  7745.  At the extend level, a formal parameter preceded by the reserved word
  7746.  CONST implies that the actual parameter is a READONLY reference parameter.
  7747.  This is especially useful for parameters of structured types, which may be
  7748.  constants, since it eliminates the need for a time-consuming value
  7749.  parameter copy.  The actual parameter can be a variable, function result,
  7750.  or constant value.
  7751.  
  7752.  No assignments can be made to the CONST parameter or any of its
  7753.  components. CONST super array types are permitted.  A CONST parameter in
  7754.  one procedure cannot be passed as a VAR parameter to another procedure.
  7755.  However, it is permissible to pass a VAR parameter in one procedure as a
  7756.  CONST parameter in another.
  7757.  
  7758.  Example of a CONST parameter:
  7759.  
  7760.       PROCEDURE ERROR (CONST ERRMSG : STRING);
  7761.  
  7762.  On a segmented machine, a CONST parameter passes an address that is really
  7763.  an offset into a default data segment. In some cases, access to objects
  7764.  residing in other segments is required. To pass these objects by reference,
  7765.  you must tell the compiler to use a segmented address that contains both
  7766.  segment register and offset values. The extend level includes the
  7767.  parameter prefix CONSTS, instead of CONST. Use of CONSTS parameters
  7768.  parallels use of VARS for formal reference parameters.
  7769.  
  7770.  Example of a CONSTS parameter:
  7771.  
  7772.       PROCEDURE CAT (VARS T : STRING; CONSTS S : STRING);
  7773.  
  7774.  A CONSTS parameter can only be used as a data parameter in procedures and
  7775.  functions, not in the declaration section of programs, procedures, and
  7776.  functions.
  7777.  
  7778.  You can also pass the value of an expression as a CONST or CONSTS
  7779.  parameter. The expression is evaluated and assigned to a temporary (hidden)
  7780.  variable in the frame of the calling procedure or function. You should
  7781.  enclose such an expression in parentheses to force its evaluation.
  7782.  
  7783.  A function identifier can be passed by reference as a VAR, VARS,
  7784.  CONST, or CONSTS parameter. The function's local variable is passed, so the
  7785.  call must occur in the function's body or in a procedure or function
  7786.  declared with the function.
  7787.  
  7788.  The value returned by a function designator can also be passed, like
  7789.  any expression, as a CONST or CONSTS parameter. Like any expression passed
  7790.  by reference, the function designator should be enclosed in parentheses, as
  7791.  shown:
  7792.  
  7793.       PROCEDURE WRITE_ANSWER (CONSTS A : INTEGER);
  7794.       BEGIN
  7795.          WRITELN ('THE ANSWER IS ,' A)
  7796.       END;
  7797.  
  7798.       FUNCTION ANSWER : INTEGER;
  7799.       BEGIN
  7800.          ANSWER := 42;
  7801.          WRITE_ANSWER (ANSWER);
  7802.          {Pass reference to local variable.}
  7803.       END;
  7804.  
  7805.       PROCEDURE HITCH_HIKE;
  7806.       BEGIN
  7807.          WRITE_ANSWER ((ANSWER))
  7808.          {Call ANSWER, assign to temporary variable,}
  7809.          {pass reference to temporary variable.}
  7810.       END;
  7811.  
  7812.  
  7813.  14.4.3  Procedural and Functional Parameters
  7814.  
  7815.  
  7816.  Procedural parameters can be used in the following circumstances:
  7817.  
  7818.      1.  in numerical analysis
  7819.  
  7820.      2.  in calling some library routines
  7821.  
  7822.      3.  in special applications
  7823.  
  7824.  In numerical analysis, you might pass a function to a procedure or
  7825.  function that finds an integral between limits, a maximum or minimum value,
  7826.  and so on. Some interesting algorithms in areas such as parsing and
  7827.  artificial intelligence also use procedural parameters.
  7828.  
  7829.  When a procedural or functional parameter is passed, the actual
  7830.  identifier is that for a procedure or function. The formal parameter is
  7831.  a procedure or function heading, including any attributes, preceded by the
  7832.  reserved word PROCEDURE or FUNCTION.
  7833.  
  7834.  For example, examine these declarations:
  7835.  
  7836.  
  7837.        TYPE DOOR  = (FRONT, BARN, CELL, DOG_HOUSE);
  7838.            SPEED  = (FAST, SLOW, NORMAL);
  7839.            DIRECTION = (OPEN, SHUT);
  7840.  
  7841.       PROCEDURE OPEN_DOOR_WIDE
  7842.          (VAR A : DOOR;  B : SPEED; C : DIRECTION);
  7843.           .
  7844.           .
  7845.       PROCEDURE SLAM_DOOR
  7846.          (VAR DR : DOOR; SP : SPEED; DIR : DIRECTION);
  7847.           .
  7848.           .
  7849.       PROCEDURE LEAVE_AJAR
  7850.          (VAR DD : DOOR; SS : SPEED; DD : DIRECTION);
  7851.  
  7852.  All of the procedures in the example have parameter lists of equal
  7853.  length. The types of the parameters are not only compatible, but also
  7854.  identical.  The formal parameters need not be identically named.
  7855.  
  7856.  A procedural or functional parameter can accept one of these
  7857.  procedures if the procedure or function is set up correctly, as shown:
  7858.  
  7859.  
  7860.      FUNCTION DOOR_STATUS (PROCEDURE MOVE_DOOR)
  7861.         (VAR X : DOOR; Y :SPEED; Z : DIRECTION);
  7862.         (VAR XX : DOOR; YY : SPEED; ZZ : DIRECTION) : INTEGER;
  7863.         {"PROCEDURE MOVE_DOOR" is the formal procedural}
  7864.         {parameter; the next two lines are other formal}
  7865.         {parameters.}
  7866.  
  7867.      BEGIN {door_status}
  7868.         DOOR_STATUS := 0;
  7869.         MOVE_DOOR (XX, YY, ZZ);
  7870.         {One of the three procedures declared}
  7871.         {previously is executed here.}
  7872.  
  7873.         IF  XX = BARN AND ZZ = SHUT
  7874.         THEN DOOR_STATUS := 1;
  7875.  
  7876.         IF  XX = CELL AND ZZ = OPEN
  7877.         THEN DOOR_STATUS := 2;
  7878.  
  7879.         IF  XX = DOG_HOUSE AND ZZ = SHUT
  7880.         THEN DOOR_STATUS := 3
  7881.      END;
  7882.  
  7883.  Use of the procedural parameter MOVE_DOOR might occur in program statements
  7884.  as follows:
  7885.  
  7886.       IF DOOR_STATUS
  7887.          (SLAM_DOOR, CELL, FAST, SHUT) = 0
  7888.       THEN
  7889.          SOCIETY := SAFE;
  7890.       IF DOOR_STATUS
  7891.          (OPEN_DOOR_WIDE, BARN, SLOW, OPEN) = 0
  7892.       THEN
  7893.          COWS_ARE_OUT := TRUE;
  7894.       IF DOOR_STATUS
  7895.          (LEAVE_AJAR, DOG_HOUSE, SLOW, OPEN) = 0
  7896.       THEN
  7897.          DOG_CAN_GET_IN := TRUE;
  7898.  
  7899.  In each case above, the actual procedure list is compatible with the formal
  7900.  list, both in number and in type of parameters.  If the parameter passed
  7901.  were a functional parameter, then the function return value would also have
  7902.  to be of an identical type.
  7903.  
  7904.  In addition, the set of attributes for both the formal and actual
  7905.  procedural type must be the same, except that the PUBLIC and ORIGIN
  7906.  attributes and EXTERN directive are ignored.
  7907.  
  7908.  A PUBLIC or EXTERN procedure, or any local procedure at any nesting
  7909.  level, can be passed to the same type of formal parameter. However, the
  7910.  PURE attribute and any calling sequence attributes must match. Also, in
  7911.  systems with segmented code addresses, a procedure or function passed as a
  7912.  parameter to an EXTERN procedure or function must itself be PUBLIC or
  7913.  EXTERN.
  7914.  
  7915.  In MS-Pascal, you cannot pass predeclared procedures and functions
  7916.  compiled as inline code; you can only pass them in called subroutines.
  7917.  Also, the READ, WRITE, ENCODE, and DECODE families are translated into
  7918.  other calls by the compiler, based on the argument types, and so cannot be
  7919.  passed. Corresponding routines in the file unit or encode/decode unit can
  7920.  be passed, however. For example, a READ of an INTEGER becomes a call to
  7921.  RTIFQQ and this procedure can be passed as a parameter.
  7922.  
  7923.  
  7924.  The following intrinsic procedures and functions cannot be passed as
  7925.  procedure or function parameters:
  7926.  
  7927.  
  7928.      1.  at the standard level of MS-Pascal:
  7929.  
  7930.          ABS           EOLN         PACK        SQR
  7931.          ARCTAN        EXP          PAGE        SQRT
  7932.          CHR           LN           PRED        SUCC
  7933.          COS           NEW          READ        UNPACK
  7934.          DISPOSE       ODD          READLN      WRITE
  7935.          EOF           ORD          SIN         WRITELN
  7936.  
  7937.      2.  at the extend and system levels of MS-Pascal:
  7938.  
  7939.          BYLONG        FLOAT4       READFN      SIZEOF
  7940.          BYWORD        HIBYTE       READSET     TRUNC
  7941.          DECODE        HIWORD       RESULT      TRUNC4
  7942.          ENCODE        LOBYTE       RETYPE      UPPER
  7943.          EVAL          LOWER        ROUND       WRD
  7944.          FLOAT         LOWORD       ROUND4
  7945.  
  7946.  When a procedure or function passed as a parameter is finally activated,
  7947.  any nonlocal variables accessed are those in effect at the time the
  7948.  procedure or function is passed as a parameter, rather than those in effect
  7949.  when it is activated. Internally, both the address of the routine and the
  7950.  address of the upper frame (in the stack) are passed.
  7951.  
  7952.  Example of formal procedure use:
  7953.  
  7954.       PROCEDURE ALPHA;
  7955.         VAR I : INTEGER;
  7956.  
  7957.         PROCEDURE DELTA;
  7958.           BEGIN
  7959.             WRITELN ('Delta done')
  7960.           END;
  7961.  
  7962.         PROCEDURE BETA (PROCEDURE XPR);
  7963.           VAR GLOB : INTEGER;
  7964.  
  7965.           PROCEDURE GAMMA;
  7966.             BEGIN GLOB := GLOB + 1 END;
  7967.           BEGIN  {Start BETA}
  7968.             GLOB := 0;
  7969.             IF I = 0
  7970.               THEN BEGIN
  7971.                  I := 1;  XPR; BETA (GAMMA)
  7972.                  END
  7973.               ELSE BEGIN
  7974.                  GLOB := GLOB + 1; XPR
  7975.                  END
  7976.           END;
  7977.  
  7978.         BEGIN  {Start ALPHA}
  7979.           I := 0;
  7980.           BETA (DELTA)
  7981.         END;
  7982.  
  7983.  The following list describes what happens in this example:
  7984.  
  7985.      1.  ALPHA is called.
  7986.  
  7987.      2.  BETA is called, passing the procedure DELTA.
  7988.  
  7989.      3.  This latter call creates an instance of GLOB on the stack (call it
  7990.          GLOB1).
  7991.  
  7992.      4.  BETA first clears GLOB1 by setting it to zero. Then, since I is 0,
  7993.          the THEN clause is executed, which sets I to one and executes XPR,
  7994.          which is bound to DELTA.
  7995.  
  7996.      5.  Therefore, 'Delta done' is written to OUTPUT.
  7997.  
  7998.      6.  Now BETA is called recursively. BETA is passed the address of
  7999.          GAMMA, and, at this time, the access path to any nonlocal variables
  8000.          used by GAMMA (i.e., GLOB1) is passed as well.
  8001.  
  8002.      7.  The second call to BETA creates another instance of GLOB (GLOB2).
  8003.          When GLOB2 is cleared this time, I is 1, so GLOB2 is incremented.
  8004.  
  8005.      8.  Then XPR is called, which is bound to GAMMA, so GAMMA is executed
  8006.          and increments the instance of GLOB active when GAMMA was passed to
  8007.          BETA, GLOB1.
  8008.  
  8009.      9.  GAMMA returns, the second BETA call returns, the first BETA call
  8010.          returns, and finally, ALPHA returns.
  8011.  
  8012.  
  8013.  
  8014.  Chapter 15  Available Procedures and Functions
  8015.  
  8016.  ───────────────────────────────────────────────────────────────────────────
  8017.  
  8018.  15.1  Categories of Available Procedures and Functions
  8019.  
  8020.         15.1.1  File System Procedures and Functions
  8021.  
  8022.         15.1.2  Dynamic Allocation Procedures
  8023.  
  8024.         15.1.3  Data Conversion Procedures and Functions
  8025.  
  8026.         15.1.4  Arithmetic Functions
  8027.  
  8028.         15.1.5  Extend Level Intrinsics
  8029.  
  8030.         15.1.6  System Level Intrinsics
  8031.  
  8032.         15.1.7  String Intrinsics
  8033.  
  8034.         15.1.8  Library Procedures and Functions
  8035.  
  8036.  15.2  Directory of Functions and Procedures
  8037.  
  8038.  
  8039.  
  8040.  All versions of Pascal predeclare a large number of common procedures
  8041.  and functions.  You do not have to declare these procedures and functions
  8042.  in a program. Since they are defined in a scope "outside" the program, you
  8043.  may redefine these identifiers
  8044.  
  8045.  To promote portability, Microsoft Pascal makes some of the predeclared
  8046.  procedures and functions available only at the extend or at the system
  8047.  level. MS-Pascal also includes some useful library procedures and functions
  8048.  that you must declare EXTERN in order to use.
  8049.  
  8050.  MS-Pascal implements three kinds of procedures and functions:
  8051.  
  8052.      1.  Some are predeclared, and the compiler translates them into other
  8053.          calls or special generated code (these you cannot pass as
  8054.          parameters).
  8055.  
  8056.      2.  Some are predeclared but you call them normally (except for a name
  8057.          change).
  8058.  
  8059.      3.  Some are not predeclared but are available as part of the MS-Pascal
  8060.          runtime library (these you must declare explicitly).
  8061.  
  8062.  However, it is more useful when discussing these procedures and functions
  8063.  to categorize them by what they do rather than by how they are implemented.
  8064.  Table 15.1 shows this categorization.
  8065.  
  8066.  
  8067.  Table 15.1
  8068.  Categories of Available Procedures and Functions
  8069. ╓┌────────────────────────┌──────────────────────────────────────────────────╖
  8070.  Category                 Purpose
  8071.  ───────────────────────────────────────────────────────────────────────────
  8072.  File system              Operate on files of different
  8073.                           modes and structures
  8074.  
  8075.  Dynamic                  Dynamically allocate and
  8076.  allocation               deallocate data structures on
  8077.                           the heap at runtime
  8078.  
  8079.  Data                     Convert data from one type to
  8080.  conversion               another
  8081.  
  8082.  Arithmetic               Perform common transcendental
  8083.                           and other numeric functions
  8084.  
  8085.  Extend level             Provide additional procedures
  8086.  intrinsics               and functions at the extend
  8087.  Category                 Purpose
  8088. intrinsics               and functions at the extend
  8089.                           level of MS-Pascal
  8090.  
  8091.  System level             Provide additional procedures
  8092.  intrinsics               and functions at the system
  8093.                           level of MS-Pascal
  8094.  
  8095.  String                   Operate on STRING and LSTRING
  8096.  intrinsics               type data
  8097.  
  8098.  Library                  Available in the MS-Pascal
  8099.                           runtime library:  they are not
  8100.                           predeclared; you must declare
  8101.                           them with the EXTERN directive
  8102.  
  8103.  
  8104.  15.1  Categories of Available Procedures and Functions
  8105.  
  8106.  
  8107.  The rest of this chapter is divided into two sections. Section 15.1
  8108.  describes each of the categories shown in the preceding table and lists the
  8109.  procedures and functions each category includes. Section 15.2 is an
  8110.  alphabetical directory of all of the available procedures and functions.
  8111.  Each entry includes the syntax and a description, plus examples and notes
  8112.  as appropriate.
  8113.  
  8114.  
  8115.  15.1.1  File System Procedures and Functions
  8116.  
  8117.  
  8118.  The MS-Pascal file system supports a variety of procedures and functions
  8119.  that operate on files of different modes and structures. These procedures
  8120.  and functions fall into three categories, as shown in Table 15.2.
  8121.  
  8122.  
  8123.  Table 15.2
  8124.  File System Procedures and Functions
  8125. ╓┌───────────────────────┌──────────────────┌────────────────────────────────╖
  8126.  Category                Procedures         Functions
  8127.  ───────────────────────────────────────────────────────────────────────────
  8128.  Primitive               GET                EOF
  8129.  Category                Procedures         Functions
  8130. Primitive               GET                EOF
  8131.                          PAGE               EOLN
  8132.                          PUT
  8133.                          RESET
  8134.                          REWRITE
  8135.  
  8136.  
  8137.  Textfile I/O            READ
  8138.                          READLN
  8139.                          WRITE
  8140.                          WRITELN
  8141.  
  8142.  
  8143.  Extend Level I/O        ASSIGN
  8144.                          CLOSE
  8145.                          DISCARD
  8146.                          READSET
  8147.                          READFN
  8148.                          SEEK
  8149.  
  8150.  For details on each of these procedures and functions, see Chapter 16,
  8151.  "File-Oriented Procedures and Functions."
  8152.  
  8153.  
  8154.  15.1.2  Dynamic Allocation Procedures
  8155.  
  8156.  
  8157.  Two procedures, NEW and DISPOSE, allow dynamic allocation and deallocation
  8158.  of data structures at runtime. NEW allocates a variable in the heap, and
  8159.  DISPOSE releases it.
  8160.  
  8161.  
  8162.  15.1.3  Data Conversion Procedures and Functions
  8163.  
  8164.  
  8165.  Use the following procedures and functions to convert data from one type to
  8166.  another:
  8167.  
  8168.      CHR              PACK             TRUNC
  8169.      FLOAT            PRED             TRUNC4
  8170.      FLOAT4           ROUND            UNPACK
  8171.      ODD              ROUND4           WRD
  8172.      ORD              SUCC
  8173.  
  8174.  Four of these convert any ordinal type to a particular ordinal type:
  8175.  
  8176.      1.  CHR (ordinal) to CHAR
  8177.  
  8178.      2.  ODD (ordinal) to BOOLEAN
  8179.  
  8180.      3.  ORD (ordinal) to INTEGER
  8181.  
  8182.      4.  WRD (ordinal) to WORD
  8183.  
  8184.  PRED and SUCC also operate on ordinal types.
  8185.  
  8186.  Six of the conversion procedures and functions convert between INTEGER
  8187.  or INTEGER4 and REAL:
  8188.  
  8189.      1.  FLOAT    converts   INTEGER    to   REAL
  8190.  
  8191.      2.  FLOAT4   converts   INTEGER4   to   REAL
  8192.  
  8193.      3.  ROUND    converts   REAL       to   INTEGER
  8194.  
  8195.      4.  ROUND4   converts   REAL       to   INTEGER4
  8196.  
  8197.      5.  TRUNC    converts   REAL       to   INTEGER
  8198.  
  8199.      6.  TRUNC4   converts   REAL       to   INTEGER4
  8200.  
  8201.  PACK and UNPACK transfer components between packed and unpacked
  8202.  arrays.
  8203.  
  8204.  
  8205.  15.1.4  Arithmetic Functions
  8206.  
  8207.  
  8208.  All arithmetic functions take a CONSTS parameter of type REAL4 or
  8209.  REAL8, or a type compatible with INTEGER (labeled "numeric" in the
  8210.  directory). ABS and SQR also take WORD and INTEGER4 values.
  8211.  
  8212.  All functions on REAL data types check for an invalid (uninitialized)
  8213.  value. They also check for particular error conditions and generate a
  8214.  runtime error message if an error condition is found.
  8215.  
  8216.  If the math checking switch is on, errors in the use of the functions
  8217.  ABS and SQR on INTEGER, WORD, and INTEGER4 data generate a runtime error
  8218.  message. If the switch is off, the result of an error is undefined.
  8219.  
  8220.  Table 15.3 lists the arithmetic functions available, along with the
  8221.  routines called depending on whether single or double precision is
  8222.  required.
  8223.  
  8224.  
  8225.  Table 15.3
  8226.  Predeclared Arithmetic Functions
  8227. ╓┌──────────┌──────────────────┌──────────────┌──────────────────────────────╖
  8228.  Name       Operation          REAL4          REAL8
  8229.  ───────────────────────────────────────────────────────────────────────────
  8230.  ABS        Absolute value     (inline)       (inline)
  8231.  ARCTAN     Arc tangent        ATSRQQ         ATDRQQ
  8232.  COS        Cosine             CNSRQQ         CNDRQQ
  8233.  EXP        Exponential        EXSRQQ         EXDRQQ
  8234.  Name       Operation          REAL4          REAL8
  8235. EXP        Exponential        EXSRQQ         EXDRQQ
  8236.  LN         Natural log        LNSRQQ         LNDRQQ
  8237.  SIN        Sine               SNSRQQ         SNDRQQ
  8238.  SQR        Square             (inline)       (inline)
  8239.  SQRT       Square root        SRSRQQ         SRDRQQ
  8240.  
  8241.  The MS-FORTRAN runtime library provides several additional REAL4 and REAL8
  8242.  functions, as shown in Table 15.4. If you use them, you must declare them
  8243.  with the EXTERN directive.
  8244.  
  8245.  
  8246.  Table 15.4
  8247.  REAL Functions from the Microsoft FORTRAN Runtime Library
  8248. ╓┌───────────────────────────┌─────────────────┌─────────────────────────────╖
  8249.  Operation                   REAL4             REAL8
  8250.  ───────────────────────────────────────────────────────────────────────────
  8251.  Arc cosine                  ACSRQQ            ACDRQQ
  8252.  Integral trunc              AISRQQ            AIDRQQ
  8253.  Integral round              ANSRQQ            ANDRQQ
  8254.  Arc sine                    ASSRQQ            ASDRQQ
  8255.  Operation                   REAL4             REAL8
  8256. Arc sine                    ASSRQQ            ASDRQQ
  8257.  Arc tangent A/B             A2SRQQ            A2DRQQ
  8258.  Hyperbolic cosine           CHSRQQ            CHDRQQ
  8259.  Decimal log                 LDSRQQ            LDDRQQ
  8260.  Modulo                      MDSRQQ            MDDRQQ
  8261.  Minimum                     MNSRQQ            MNDRQQ
  8262.  Maximum                     MXSRQQ            MXDRQQ
  8263.  Power (REAL8**INTG4)                          PIDRQQ
  8264.  Power (REAL4**INTG4)        PISRQQ
  8265.  Power (REAL ** REAL)        PRSRQQ            PRDRQQ
  8266.  Hyperbolic sine             SHSRQQ            SHDRQQ
  8267.  Hyperbolic tangent          THSRQQ            THDRQQ
  8268.  Tangent                     TNSRQQ            TNDRQQ
  8269.  
  8270.  Some common mathematical functions are not standard in Pascal, but are
  8271.  relatively simple to accomplish with program statements or to define as
  8272.  functions in a program. Some typical definitions follow:
  8273.  
  8274.      SIGN (X) is ORD (X > 0) - ORD (X < 0)
  8275.      POWER (X, Y) is EXP (Y * LN (X))
  8276.  
  8277.  You could also write your own functions in MS-Pascal to do the same thing.
  8278.  Defining functions like these is a good opportunity to use the PURE
  8279.  attribute (to obtain more efficient code). For example:
  8280.  
  8281.      FUNCTION POWER (A, B : REAL) : REAL [PURE];
  8282.      BEGIN
  8283.        IF A <= 0 THEN
  8284.           ABORT ('Nonplus real to power', 24, 0);
  8285.           POWER := EXP (B * LN (A))
  8286.      END;
  8287.  
  8288.  
  8289.  15.1.5  Extend Level Intrinsics
  8290.  
  8291.  
  8292.  At the extend level of MS-Pascal, the following intrinsic procedures
  8293.  and functions are available:
  8294.  
  8295.      ABORT             EVAL             LOWORD
  8296.      BYLONG            HIBYTE           RESULT
  8297.      BYWORD            HIWORD           SIZEOF
  8298.      DECODE            LOBYTE           UPPER
  8299.      ENCODE            LOWER
  8300.  
  8301.  Several of these are used to compose and decompose one-byte, two-byte,
  8302.  and four-byte items: HIBYTE, LOBYTE, BYWORD, HIWORD, LOWORD, and BYLONG.
  8303.  
  8304.  ENCODE and DECODE convert between internal and string forms of
  8305.  variables. ABORT invokes a runtime error.
  8306.  
  8307.  The others, EVAL, LOWER, UPPER, RESULT, and SIZEOF, are used in
  8308.  special situations (described for each function in Section 15.2,
  8309.  "Directory of Functions and Procedures").
  8310.  
  8311.  
  8312.  15.1.6  System Level Intrinsics
  8313.  
  8314.  
  8315.  Several additional intrinsic procedures and functions are available at
  8316.  the system level:
  8317.  
  8318.      FILLC               MOVESL
  8319.      FILLSC              MOVESR
  8320.      MOVEL               RETYPE
  8321.      MOVER
  8322.  
  8323.  The MOVE and FILL procedures perform low-level operations on byte
  8324.  strings. RETYPE changes the type of an expression arbitrarily.
  8325.  
  8326.  
  8327.  15.1.7  String Intrinsics
  8328.  
  8329.  
  8330.  The string intrinsics feature provides a set of procedures and
  8331.  functions, some of which operate on STRINGs and LSTRINGs, and some on
  8332.  LSTRINGs only as shown in Table 15.5:
  8333.  
  8334.         Table 15.5
  8335.         String Procedures and Functions
  8336. ╓┌─────────────────────────┌─────────────────────────────────────────────────╖
  8337.         Name               Parameter
  8338.         ────────────────────────────────────────────
  8339.         Name               Parameter
  8340.         ────────────────────────────────────────────
  8341.         CONCAT             STRING
  8342.         DELETE             STRING
  8343.         INSERT             STRING
  8344.         COPYLST            STRING
  8345.  
  8346.         COPYSTR            STRING or LSTRING
  8347.         POSITN             STRING or LSTRING
  8348.         SCANEQ             STRING or LSTRING
  8349.         SCANNE             STRING or LSTRING
  8350.  
  8351.  
  8352.  15.1.8  Library Procedures and Functions
  8353.  
  8354.  
  8355.  The following routines are not predeclared, but are available to you in
  8356.  the MS-Pascal runtime library. You must declare them, with the EXTERN
  8357.  directive, before using them in a program.
  8358.  
  8359.      1.  Initialization and termination routines
  8360.  
  8361.          BEGOQQ and ENDOQQ are called during initialization and termination,
  8362.          respectively.  You might use them to invoke a debugger or to write
  8363.          customized messages, such as the time of execution, to the terminal
  8364.          screen.  BEGXQQ may be called to restart a program and ENDXQQ to
  8365.          terminate it.
  8366.  
  8367.      2.  Heap management routines
  8368.  
  8369.          Heap management routines complement the standard NEW and DISPOSE
  8370.          procedures and include:
  8371.  
  8372.          ALLHQQ
  8373.          FREECT
  8374.          MARKAS
  8375.          MEMAVL
  8376.          RELEAS
  8377.  
  8378.      3.  Interrupt routines
  8379.  
  8380.          These routines handle interrupt processing, although the actual
  8381.          effect varies with the target machine:
  8382.  
  8383.          ENABIN
  8384.          DISABIN
  8385.          VECTIN
  8386.  
  8387.      4.  Terminal I/O routines
  8388.  
  8389.          The following routines support direct input to and output from
  8390.          your terminal:
  8391.  
  8392.          GTYUQQ
  8393.          PTYUQQ
  8394.          PLYUQQ
  8395.  
  8396.      5.  Semaphore routines
  8397.  
  8398.          The two procedures, LOCKED and UNLOCK, provide a binary semaphore
  8399.          capability. You can use them to ensure exclusive access of a
  8400.          resource in a concurrent system.
  8401.  
  8402.      6.  No-overflow arithmetic functions
  8403.  
  8404.          These functions implement 16-bit and 32-bit modulo arithmetic.
  8405.          Overflow or carry is returned, instead of invoking a runtime error.
  8406.  
  8407.          LADDOK
  8408.          LMULOK
  8409.          SADDOK
  8410.          SMULOK
  8411.          UADDOK
  8412.          UMULOK
  8413.  
  8414.      7.  Clock routines
  8415.  
  8416.          These provide operating system clock information:
  8417.  
  8418.          TIME
  8419.          DATE
  8420.          TICS
  8421.  
  8422.  
  8423.  15.2  Directory of Functions and Procedures
  8424.  
  8425.  
  8426.  This section contains a list of all available procedures and functions,
  8427.  both those that are predeclared and those library routines that may be used
  8428.  if declared EXTERN. Each entry includes the heading, the category to which
  8429.  the operation belongs, and a description of what the procedure or function
  8430.  does. Notes and examples are included as appropriate. The headings given
  8431.  are the same for both REAL4 or REAL8, unless specifically stated otherwise.
  8432.  
  8433.  
  8434.  PROCEDURE ABORT (CONST STRING, WORD, WORD);
  8435.  
  8436.        An extend level intrinsic procedure. Halts program execution in the
  8437.        same way as an internal runtime error. The STRING (or LSTRING) is an
  8438.        error message. The string parameter is a CONST, not a CONSTS
  8439.        parameter. The first WORD is an error code; the second WORD can be
  8440.        anything. The second WORD is sometimes used to return a file error
  8441.        status code from the operating system.
  8442.  
  8443.        The parameters, as well as any information about the machine
  8444.        state (program counter, frame pointer, stack pointer) and the source
  8445.        position of the ABORT call (if the $line and/or $entry debugging
  8446.        switches are on), are given to you in a termination message or are
  8447.        available to the debugging package.
  8448.  
  8449.        If the $runtime switch is on, then error messages report the
  8450.        location of the procedure or function that has called the routine in
  8451.        which abort was called. If $runtime is on, $line and $entry should
  8452.        be off, and routines in a source file should only call other $runtime
  8453.        routines.
  8454.  
  8455.  
  8456.  FUNCTION ABS (X : NUMERIC) : NUMERIC;
  8457.  
  8458.        An arithmetic function. Returns the absolute value of X. Both X and
  8459.        the return value are of the same numeric type: REAL4, REAL8, INTEGER,
  8460.        WORD, or INTEGER4. Since WORD values are unsigned, ABS (X) always
  8461.        returns X if X is of type WORD.
  8462.  
  8463.  
  8464.  FUNCTION ACSRQQ (CONSTS A : REAL4) : REAL4;
  8465.  FUNCTION ACDRQQ (CONSTS A : REAL8) : REAL8;
  8466.  
  8467.        Arithmetic functions. Return the arc cosine of A. Both A and the
  8468.        return value are of type REAL4 or REAL8, as shown. These functions
  8469.        are from the MS-FORTRAN runtime library and must be declared EXTERN
  8470.        before use.
  8471.  
  8472.  
  8473.  FUNCTION AISRQQ (CONSTS A : REAL4) : REAL4;
  8474.  FUNCTION AIDRQQ (CONSTS A : REAL8) : REAL8;
  8475.  
  8476.        Arithmetic functions. Return the integral part of A, truncated toward
  8477.        zero. Both A and the return value are of type REAL4 or REAL8, as
  8478.        shown.  These functions are from the MS-FORTRAN runtime library and
  8479.        must be declared EXTERN before use.
  8480.  
  8481.  
  8482.  FUNCTION ALLHQQ (SIZE : WORD) : WORD;
  8483.  
  8484.        A library routine (heap management function).  Returns zero if
  8485.        the heap is full, one if the heap structure is in error, or MAXWORD
  8486.        if the allocator has been interrupted.  Otherwise, it returns the
  8487.        pointer value for an allocated variable with the size requested.
  8488.  
  8489.        Generally, you use ALLHQQ with the RETYPE function.  For
  8490.        example:
  8491.  
  8492.            P_VAR := RETYPE (P_TYPE, ALLHQQ (28));
  8493.            {RETYPE converts the value returned by}
  8494.            {ALLHQQ (28) to the type P_TYPE.}
  8495.            {This value is assigned to P_VAR.}
  8496.  
  8497.            IF WRD (P_VAR) < 2 THEN GO_ABORT;
  8498.            is then checked for a heap}
  8499.            {full or heap structure error.}
  8500.  
  8501.  
  8502.  FUNCTION ALLMQQ (WANTS : WORD) : ADSMEM;
  8503.  
  8504.        A library routine (segmented heap management function). This
  8505.        function returns a long segmented address of type ADSMEM. ALLMQQ
  8506.        takes a parameter "wants" that is a memory request in bytes.
  8507.  
  8508.        A number "0" in the ".r" field of the segmented address returned by
  8509.        ALLMQQ indicates that memory of the requested "wants" size could not
  8510.        be allocated. A number "1" indicates that the long segmented heap is
  8511.        invalid.
  8512.  
  8513.        ALLMQQ may not be available in your implementation of MS-Pascal;
  8514.        see the "Version Specifics" Appendix of your Microsoft Pascal
  8515.        Compiler User's Guide.
  8516.  
  8517.  
  8518.  FUNCTION ANSRQQ (CONSTS A : REAL4) : REAL4;
  8519.  FUNCTION ANDRQQ (CONSTS A : REAL8) : REAL8;
  8520.  
  8521.        Arithmetic functions. Like AISRQQ and AIDRQQ, return the truncated
  8522.        integral part of A, but round away from zero. Both A and the return
  8523.        value are of type REAL4 or REAL8, as shown. These functions are from
  8524.        the MS-FORTRAN runtime library and must be declared EXTERN before
  8525.        use.
  8526.  
  8527.  
  8528.  FUNCTION ARCTAN (X : REAL) : REAL;
  8529.  
  8530.        An arithmetic function. Returns the arc tangent of X in radians.
  8531.        Both X and the return value are of type REAL. To force a particular
  8532.        precision, declare ATSRQQ (CONSTS REAL4) and/or ATDRQQ (CONSTS REAL8)
  8533.        and use them instead.
  8534.  
  8535.  
  8536.  FUNCTION ASSRQQ (CONSTS A : REAL4) : REAL4;
  8537.  FUNCTION ASDRQQ (CONSTS A : REAL8) : REAL8;
  8538.  
  8539.        Arithmetic functions. Return the arc sine of A. Both A and the
  8540.        return value are of type REAL4 or REAL8, as shown. These functions
  8541.        are from the MS-FORTRAN runtime library and must be declared EXTERN
  8542.        before use.
  8543.  
  8544.  
  8545.  PROCEDURE ASSIGN (VAR F; CONSTS N : STRING);
  8546.  
  8547.        A file system procedure (extend level I/O). Assigns an operating
  8548.        system filename in a STRING (or LSTRING) to a file F.
  8549.  
  8550.        See Section 16.3.1, "Extend Level Procedures," for a description
  8551.        of ASSIGN.
  8552.  
  8553.  
  8554.  FUNCTION ATSRQQ (CONSTS A : REAL4) : REAL4;
  8555.  FUNCTION ATDRQQ (CONSTS A : REAL8) : REAL8;
  8556.  
  8557.        See FUNCTION ARCTAN
  8558.  
  8559.  
  8560.  FUNCTION A2SRQQ (A, B : REAL4) : REAL4;
  8561.  FUNCTION A2DRQQ (A, B : REAL8) : REAL8;
  8562.  
  8563.        Arithmetic functions. Return the arc tangent of (A/B). Both A and B,
  8564.        as well as the return value, are of type REAL4 or REAL8, as shown.
  8565.        These functions are from the MS-FORTRAN runtime library and must be
  8566.        declared EXTERN before use.
  8567.  
  8568.  
  8569.  PROCEDURE BEGOQQ;
  8570.  
  8571.        A library routine (initialization). BEGOQQ is called during
  8572.        initialization, and the default version does nothing. However, you
  8573.        may write your own version of BEGOQQ, if you want, to invoke a
  8574.        debugger or to write customized messages, such as the time of
  8575.        execution, to a terminal screen.
  8576.  
  8577.        See also PROCEDURE ENDOQQ.
  8578.  
  8579.  
  8580.  PROCEDURE BEGXQQ;
  8581.  
  8582.        A library routine (initialization). After your program is linked
  8583.        and loaded, BEGXQQ is the defined entry point for the load module.
  8584.  
  8585.        As the overall initialization routine, BEGXQQ performs the
  8586.        following actions:
  8587.  
  8588.        1.  It resets the stack and the heap.
  8589.  
  8590.        2.  It initializes the file system.
  8591.  
  8592.        3.  It calls BEGOQQ.
  8593.  
  8594.        4.  It calls the program body.
  8595.  
  8596.        BEGXQQ may be useful for restarting after a catastrophic error in
  8597.        a ROM-based system. However, invoking this procedure to restart a
  8598.        program does not take care of closing any files that may have
  8599.        previously been opened. Similarly, it does not re-initialize
  8600.        variables originally set in a VALUE section or with the
  8601.        initialization switch on.
  8602.  
  8603.  
  8604.  FUNCTION BYLONG (INTEGER-WORD, INTEGER-WORD) : INTEGER4;
  8605.  
  8606.        An extend level intrinsic function. Converts WORDs or INTEGERs (or
  8607.        the LOWORDs of INTEGER4s) to an INTEGER4 value. BYLONG concatenates
  8608.        its operands:
  8609.  
  8610.        BYLONG (A,B) =
  8611.        ORD (LOWORD (A)) * 65535 + WRD (HIWORD (B))
  8612.  
  8613.        If the first value is of type WORD, its most significant bit
  8614.        becomes the sign of the result.
  8615.  
  8616.  
  8617.  FUNCTION BYWORD (ONE-BYTE, ONE-BYTE) : WORD;
  8618.  
  8619.        An extend level intrinsic function. Converts bytes (or the
  8620.        LOBYTEs of INTEGERs or WORDs) to a WORD value. Takes two parameters
  8621.        of any ordinal type. BYWORD returns a WORD with the first byte in
  8622.        the most significant part and the second byte in the least
  8623.        significant part:
  8624.  
  8625.           BYWORD (A,B) = LOBYTE(A) * 256 + LOBYTE(B)
  8626.  
  8627.        If the first value is of type WORD, its most significant bit
  8628.        becomes the sign of the result.
  8629.  
  8630.  
  8631.  FUNCTION CHR (X : ORDINAL) : CHAR;
  8632.  
  8633.        A data conversion function. Converts any ordinal type to CHAR. The
  8634.        ASCII code for the result is ORD (X). This is an extension to the
  8635.        ISO standard, which requires X to be of type INTEGER. An error
  8636.        occurs if ORD (X) > 255 or ORD (X) < 0. However, the error is caught
  8637.        only if the range checking switch is on.
  8638.  
  8639.  
  8640.  FUNCTION CHSRQQ (CONSTS A : REAL4) : REAL4;
  8641.  FUNCTION CHDRQQ (CONSTS A : REAL8) : REAL8;
  8642.  
  8643.        Arithmetic functions. Return the hyperbolic cosine of A. Both A and
  8644.        the return value are of type REAL4 or REAL8, as shown. These
  8645.        functions are from the MS-FORTRAN runtime library and must be
  8646.        declared EXTERN before use.
  8647.  
  8648.  
  8649.  PROCEDURE CLOSE (VAR F);
  8650.  
  8651.        A file system procedure (extend level I/O). Performs an operating
  8652.        system close on a file, ensuring that the file access is terminated
  8653.        correctly.
  8654.  
  8655.        See Section 16.3.1, "Extend Level Procedures," for a description
  8656.        of CLOSE.
  8657.  
  8658.  FUNCTION CNSRQQ (CONSTS A : REAL4) : REAL4;
  8659.  FUNCTION CNDRQQ (CONSTS A : REAL4) : REAL4;
  8660.  
  8661.        See FUNCTION COS.
  8662.  
  8663.  
  8664.  PROCEDURE CONCAT (VARS D : LSTRING; CONSTS S : STRING);
  8665.  
  8666.        A string intrinsic procedure. Concatenates S to the end of D.
  8667.        The length of D increases by the length of S. An error occurs if D
  8668.        is too small, i.e., if UPPER (D) < D.LEN + UPPER (S).
  8669.  
  8670.  
  8671.  PROCEDURE COPYLST (CONSTS S : STRING; VARS D : LSTRING);
  8672.  
  8673.        A string intrinsic procedure. Copies S to LSTRING D. The length of D
  8674.        is set to UPPER (S). An error occurs if the length of S is greater
  8675.        than the maximum length of D, i.e., if UPPER (S) > UPPER (D).
  8676.  
  8677.  
  8678.  PROCEDURE COPYSTR (CONSTS S : STRING; VARS D : STRING);
  8679.  
  8680.        A string intrinsic procedure. Copies S to STRING D. The remainder of
  8681.        D is set to blanks if UPPER (S) < UPPER (D). An error occurs if the
  8682.        length of S is greater than the maximum length of D, i.e., if
  8683.        UPPER (S) > UPPER (D).
  8684.  
  8685.  
  8686.  FUNCTION COS (X : NUMERIC) : REAL;
  8687.  
  8688.        An arithmetic function. Returns the cosine of X in radians. Both X
  8689.        and the return value are of type REAL. To force a particular
  8690.        precision, declare CNSRQQ (CONSTS REAL4) and/or CNDRQQ (CONSTS REAL8)
  8691.        and use them instead.
  8692.  
  8693.  
  8694.  PROCEDURE DATE (VAR S : STRING);
  8695.  
  8696.        A clock procedure. If available, this procedure assigns the current
  8697.        date to its STRING (or LSTRING) variable. If an LSTRING is passed as
  8698.        the parameter, you must set the length you want before calling the
  8699.        procedure. The format depends on the target operating system.
  8700.  
  8701.  
  8702.  FUNCTION DECODE (CONST LSTR : LSTRING, X : M : N) : BOOLEAN;
  8703.  
  8704.        An extend level intrinsic function. Converts the character string in
  8705.        the LSTRING to its internal representation and assigns this to X. If
  8706.        the character string is not a valid external ASCII representation of
  8707.        a value whose type is assignment compatible with X, DECODE returns
  8708.        FALSE and the value of X is undefined.
  8709.  
  8710.        DECODE works exactly the same as the READ procedure, including
  8711.        the use of M and N parameters (see Section 16.2.2, "READ Formats,"
  8712.        for a discussion of these parameters). When X is a subrange, DECODE
  8713.        returns FALSE if the value is out of range (regardless of the setting
  8714.        of the range checking switch.) Leading and trailing spaces and tabs
  8715.        in the LSTRING are ignored. All other characters in the LSTRING must
  8716.        be part of the representation.
  8717.  
  8718.        X must be one of the types INTEGER, WORD, enumerated, one of
  8719.        their subranges, BOOLEAN, REAL4, REAL8, INTEGER4, or a pointer
  8720.        (address types need the .R or .S suffix).
  8721.  
  8722.        In a segmented memory environment, the LSTR parameter must
  8723.        reside in the default data segment.
  8724.  
  8725.        See also FUNCTION ENCODE.
  8726.  
  8727.  
  8728.  PROCEDURE DELETE (VARS D : LSTRING; I, N : INTEGER);
  8729.  
  8730.        A string intrinsic procedure. Deletes N characters from D, starting
  8731.        with D [I].  An error occurs if an attempt is made to delete more
  8732.        characters starting at I than it is possible to delete, i.e., if
  8733.        D.LEN < (I + N - 1).
  8734.  
  8735.  
  8736.  PROCEDURE DISBIN;
  8737.  
  8738.        A library routine (interrupt). Along with ENABIN and VECTIN,
  8739.        DISBIN handles interrupt processing. DISBIN disables interrupts;
  8740.        ENABIN enables interrupts; VECTIN sets an interrupt vector. The
  8741.        effect of these procedures varies with the target machine. See
  8742.        Appendix B, "Version Specifics," in the Microsoft Pascal Compiler
  8743.        User's Guide for information about your implementation.
  8744.  
  8745.  
  8746.  PROCEDURE DISCARD (VAR F);
  8747.  
  8748.        A file system procedure (extend level I/O). Closes and deletes an
  8749.        open file.
  8750.  
  8751.        See Section 16.3.1, "Extend Level Procedures," for a description
  8752.        of DISCARD.
  8753.  
  8754.  
  8755.  PROCEDURE DISMQQ (BLOCK : ADSMEM);
  8756.  
  8757.        A library routine (segmented heap management function). This
  8758.        function takes an ADSMEM generated by ALLMQQ or GETMQQ and invokes
  8759.        FREMQQ to return the space described by the ADSMEM to the long heap
  8760.        memory pool. If errors occur, runtime messages are generated.
  8761.  
  8762.        DISMQQ may not be available in your implementation of MS-Pascal.
  8763.        See the "Version Specifics" appendix of your Microsoft Pascal
  8764.        Compiler User's Guide for details.
  8765.  
  8766.  
  8767.  PROCEDURE DISPOSE (VARS P : POINTER);
  8768.  
  8769.        A dynamic allocation procedure (short form). Releases the memory
  8770.        used for the variable pointed to by P. P must be a valid pointer; it
  8771.        may not be NIL, uninitialized, or pointing at a heap item that
  8772.        already has been DISPOSEd. These are checked if the NIL check switch
  8773.        is on.
  8774.  
  8775.        P should not be a reference parameter or a WITH statement record
  8776.        pointer, but these errors are not caught. A DISPOSE of a WITH
  8777.        statement record can be done at the end of the WITH statement without
  8778.        problem.
  8779.  
  8780.        If the variable is a super array type or a record with variants,
  8781.        you may safely use the short form of DISPOSE to release the variable,
  8782.        regardless of whether it was allocated with the long or short form of
  8783.        NEW. Using the short form of DISPOSE on a heap variable allocated
  8784.        with the long form of NEW is an ISO-defined error not caught in
  8785.        MS-Pascal.
  8786.  
  8787.  
  8788.  PROCEDURE DISPOSE
  8789.  VARS P : POINTER;T1,T2,...TN : TAGS);
  8790.  
  8791.        A dynamic allocation procedure (long form). The long form of DISPOSE
  8792.        works the same as the short form. However, the long form checks the
  8793.        size of the variable against the size implied by the tag field or
  8794.        array upper bound values T1, T2, ... Tn. These tag values should be
  8795.        the same as defined in the corresponding NEW procedure.
  8796.  
  8797.        See also the SIZEOF function, which uses the same array upper
  8798.        bounds or tag value parameters to return the number of bytes in a
  8799.        variable.
  8800.  
  8801.  
  8802.  PROCEDURE ENABIN;
  8803.  
  8804.        A library routine (interrupt handling). Along with DISBIN and
  8805.        VECTIN, ENABIN handles interrupt processing. ENABIN enables
  8806.        interrupts; DISBIN disables interrupts; VECTIN sets an interrupt
  8807.        vector. The effect of these procedures may vary with the target
  8808.        machine. See Appendix B, "Version Specifics," in the Microsoft
  8809.        Pascal Compiler User's Guide for information about your
  8810.        implementation.
  8811.  
  8812.  
  8813.  FUNCTION ENCODE (VAR LSTR : LSTRING, X : M : N) : BOOLEAN;
  8814.  
  8815.        An extend level intrinsic function. Converts the expression X to its
  8816.        external ASCII representation and puts this character string into
  8817.        LSTR. Returns TRUE, unless the LSTRING is too small to hold the
  8818.        string generated. In this case, ENCODE returns FALSE and the value of
  8819.        the LSTR is undefined. ENCODE works exactly the same as the WRITE
  8820.        procedure, including the use of M and N parameters (see Section
  8821.        16.2.4, "WRITE Formats," for a discussion of these parameters).
  8822.  
  8823.        X must be one of the types INTEGER, WORD, enumerated, one of
  8824.        their subranges, BOOLEAN, REAL4, REAL8, INTEGER4, or a pointer
  8825.        (address types need the .R or .S suffix).
  8826.  
  8827.        In a segmented memory environment, the LSTR parameter must
  8828.        reside in the default data segment.
  8829.  
  8830.        See also FUNCTION DECODE.
  8831.  
  8832.  
  8833.  PROCEDURE ENDOQQ;
  8834.  
  8835.        A library procedure (termination). ENDOQQ is called during
  8836.        termination and the default version does nothing. However, you may
  8837.        write your own version of ENDOQQ, if you want, to invoke a debugger
  8838.        or to write customized messages, such as the time of execution, to a
  8839.        terminal screen.
  8840.  
  8841.        Since ENDOQQ is called after errors are processed, if ENDOQQ
  8842.        itself invokes an error, the result is an infinite termination loop.
  8843.  
  8844.        See also PROCEDURE BEGOQQ.
  8845.  
  8846.  
  8847.  PROCEDURE ENDXQQ;
  8848.  
  8849.        The termination procedure. ENDXQQ is the overall termination
  8850.        routine and performs the following actions:
  8851.  
  8852.        1.  It calls ENDOQQ.
  8853.  
  8854.        2.  It terminates the file system (closing any open files).
  8855.  
  8856.        3.  It returns to the target operating system (or whatever called
  8857.            BEGXQQ).
  8858.  
  8859.        ENDXQQ may be useful for ending program execution from inside a
  8860.        procedure or function, without calling ABORT. ENDXQQ corresponds to
  8861.        the HALT procedure in other Pascals.
  8862.  
  8863.  
  8864.  FUNCTION EOF : BOOLEAN;
  8865.  FUNCTION EOF (VAR F) : BOOLEAN;
  8866.  
  8867.        A file system function. Indicates whether the current position
  8868.        of the file is at the end of the file F for SEQUENTIAL and TERMINAL
  8869.        file modes. EOF with no parameters is the same as EOF (INPUT).
  8870.  
  8871.        See Section 16.1.3, "EOF and EOLN," for a more complete
  8872.        description of EOF.
  8873.  
  8874.  
  8875.  FUNCTION EOLN : BOOLEAN;
  8876.  FUNCTION EOLN (VAR F) : BOOLEAN;
  8877.  
  8878.        A file system function. Indicates whether the current position
  8879.        of the file is at the end of a line in the textfile F. EOLN with no
  8880.        parameters is the same as EOLN (INPUT).
  8881.  
  8882.        See Section 16.1.3, "EOF and EOLN," for a description of EOLN.
  8883.  
  8884.  
  8885.  PROCEDURE EVAL (EXPRESSION, EXPRESSION, ... );
  8886.  
  8887.        An extend level intrinsic procedure. Evaluates expression
  8888.        parameters only, but accepts any number of parameters of any type.
  8889.        EVAL is used to evaluate an expression as a statement; it is commonly
  8890.        used to evaluate a function for its side effects only, without using
  8891.        the function return value.
  8892.  
  8893.  
  8894.  FUNCTION EXP (X : NUMERIC) : REAL;
  8895.  
  8896.        An arithmetic function. Returns the exponential value of X (i.e.,
  8897.        to the X). Both X and the return value are of type REAL. To force a
  8898.        particular precision, declare EXSRQQ (CONSTS REAL4) and/or EXDRQQ
  8899.        (CONSTS REAL8) and use them instead.
  8900.  
  8901.  
  8902.  FUNCTION EXSRQQ (CONSTS A : REAL4) : REAL4;
  8903.  FUNCTION EXDRQQ (CONSTS A : REAL8) : REAL8;
  8904.  
  8905.        See FUNCTION EXP.
  8906.  
  8907.  
  8908.  PROCEDURE FILLC (D : ADRMEM; N : WORD; C : CHAR);
  8909.  
  8910.        A system level intrinsic procedure. Fills D with N copies of the
  8911.        CHAR C. No bounds checking is done.
  8912.  
  8913.        See also PROCEDURE FILLSC for segmented address types. The MOV
  8914.        and FILL procedures take value parameters of type ADRMEM and ADSMEM,
  8915.        but since all ADR (or ADS) types are compatible, the ADR (or ADS) of
  8916.        any variable or constant can be used as the actual parameter. These
  8917.        are dangerous but sometimes useful procedures.
  8918.  
  8919.  
  8920.  PROCEDURE FILLSC (D : ADSMEM; N : WORD; C : CHAR);
  8921.  
  8922.        A system level intrinsic procedure. Fills D with N copies of the CHAR
  8923.        C. No bounds checking is done.
  8924.  
  8925.        See also PROCEDURE FILLC for relative address types. The MOV
  8926.        and FILL procedures take value parameters of type ADRMEM and ADSMEM,
  8927.        but since all ADR (or ADS) types are compatible, the ADR (or ADS) of
  8928.        any variable or constant can be used as the actual parameter. These
  8929.        are dangerous but sometimes useful procedures.
  8930.  
  8931.  
  8932.  FUNCTION FLOAT (X : INTEGER) : REAL;
  8933.  
  8934.        A data conversion function. Converts an INTEGER value to a REAL
  8935.        value.  You normally don't need this function, since INTEGER-to-REAL
  8936.        is usually done automatically. However, because FLOAT is needed by
  8937.        the runtime package, it is included at the standard level.
  8938.  
  8939.  
  8940.  FUNCTION FLOAT4 (X : INTEGER4) : REAL;
  8941.  
  8942.        A data conversion function. Converts an INTEGER4 value to a REAL
  8943.        value. This type conversion is also done automatically; however, it
  8944.        is possible to lose precision. (Losing precision is not an error.)
  8945.  
  8946.  
  8947.  FUNCTION FREECT (SIZE : WORD) : WORD;
  8948.  
  8949.        A library function. Returns an estimate of the number of times
  8950.        NEW could be called to allocate heap variables with length SIZE
  8951.        bytes. FREECT takes into account DISPOSE and adjacent free blocks
  8952.        and is generally used with the SIZEOF function. However, it does not
  8953.        assume any stack space will be needed. Since stack space generally
  8954.        will be needed, the value returned should be reduced accordingly.
  8955.  
  8956.        Example:
  8957.  
  8958.           IF FREECT (SIZEOF (REC, TRUE, 5)) > 2
  8959.             THEN DO_SOMETHING
  8960.  
  8961.  
  8962.  FUNCTION FREMQQ (BLOCK : ADSMEM) : WORD;
  8963.  
  8964.        A library routine (segmented heap management function). This
  8965.        function takes an ADSMEM generated by ALLMQQ or GETMQQ and returns
  8966.        the space described by the ADSMEM to the long heap memory pool. The
  8967.        function returns a word value. If the word value is 0, FREMQQ
  8968.        encountered no errors. If the word value is 1, the release of memory
  8969.        was in error.
  8970.  
  8971.        FREMQQ may not be available on your system; see your Microsoft Pascal
  8972.        Compiler User's Guide.
  8973.  
  8974.  
  8975.  PROCEDURE GET (VAR F);
  8976.  
  8977.        A file system procedure. GET either reads the currently pointed-to
  8978.        component of F to the buffer variable F^ and advances the file
  8979.        pointer, or sets the buffer variable status to empty.
  8980.  
  8981.        See Section 16.1.1, "GET and PUT," for a description of GET.
  8982.  
  8983.  
  8984.  FUNCTION GETMQQ (WANTS : WORD) : ADSMEM;
  8985.  
  8986.        A library routine (segmented heap management function). This
  8987.        function returns a long segmented address of type ADSMEM. GETMQQ
  8988.        takes a parameter "wants" that is a memory request in bytes.
  8989.  
  8990.        GETMQQ invokes ALLMQQ but in addition, issues error messages if
  8991.        ALLMQQ fails. GETMQQ may not be available on your system; see your
  8992.        Microsoft Pascal Compiler User's Guide.
  8993.  
  8994.  
  8995.  FUNCTION GTYUQQ (LEN : WORD; LOC : ADSMEM) : WORD;
  8996.  
  8997.        A library function (terminal I/O). Reads a maximum of LEN
  8998.        characters from the terminal keyboard and stores them in memory
  8999.        beginning at the address LOC. The return value is the number of
  9000.        characters actually read. GTYUQQ always reads the entire line you
  9001.        enter. Any characters typed beyond the end of the buffer length are
  9002.        lost.
  9003.  
  9004.        Example:
  9005.  
  9006.            LSTR.LEN := GTYUQQ (UPPER(LSTR), ADS LSTR(1));
  9007.  
  9008.        Together with PTYUQQ and PLYUQQ, GTYUQQ is useful for doing
  9009.        terminal I/O in a low-overhead environment. These functions are part
  9010.        of a collection of routines called Unit U, which implements the MS-
  9011.        Pascal file system. (See Section 10.2, "An Overview of the File
  9012.        System," in your Microsoft Pascal Compiler User's Guide for further
  9013.        information on Unit U.)
  9014.  
  9015.  
  9016.  FUNCTION HIBYTE (INTEGER-WORD) : BYTE;
  9017.  
  9018.        An extend level intrinsic function. Returns the most significant
  9019.        byte of an INTEGER or WORD. Depending on the target processor, the
  9020.        most significant byte may be the first or the second addressed byte
  9021.        of the word.
  9022.  
  9023.        See also FUNCTION LOBYTE.
  9024.  
  9025.  
  9026.  FUNCTION HIWORD (INTEGER4) : WORD;
  9027.  
  9028.        An extend level intrinsic function. Returns the high-order word of
  9029.        the four bytes of the INTEGER4. The sign bit of the INTEGER4 becomes
  9030.        the most significant bit of the WORD.
  9031.  
  9032.        See also FUNCTION LOWORD.
  9033.  
  9034.  
  9035.  PROCEDURE INSERT (CONSTS S : STRING;
  9036.  VARS D : LSTRING; I : INTEGER);
  9037.  
  9038.        A string intrinsic procedure. Inserts S starting just before D [I].
  9039.        An error occurs if D is too small, i.e., if
  9040.  
  9041.            UPPER (D) < UPPER (S) + D.LEN + 1
  9042.  
  9043.        or if
  9044.  
  9045.            D.LEN < I
  9046.  
  9047.  
  9048.  FUNCTION LADDOK
  9049.  (A, B : INTEGER4; VAR C : INTEGER4) : BOOLEAN;
  9050.  
  9051.        A library routine (no-overflow arithmetic). Sets C equal to A plus
  9052.        B. One of two functions that do 32-bit signed arithmetic without
  9053.        causing a runtime error, even if the arithmetic debugging switch is
  9054.        on. Both LADDOK and LMULOK return TRUE if there is no overflow, and
  9055.        FALSE if there is. These routines are useful for extended-precision
  9056.        arithmetic, or modulo 2^32 arithmetic, or arithmetic based on user
  9057.        input data.
  9058.  
  9059.  
  9060.  FUNCTION LDSRQQ (CONSTS A : REAL4) : REAL4;
  9061.  FUNCTION LDDRQQ (CONSTS A : REAL8) : REAL8;
  9062.  
  9063.        Arithmetic functions. Return the logarithm, base 10, of A. Both A
  9064.        and the return value are of type REAL4 or REAL8, as shown. These
  9065.        functions are from the MS-FORTRAN runtime library and must be
  9066.        declared EXTERN before use.
  9067.  
  9068.  
  9069.  FUNCTION LMULOK
  9070.  (A, B : INTEGER4; VAR C : INTEGER4) : BOOLEAN;
  9071.  
  9072.        A library routine (no-overflow arithmetic). Sets C equal to A times
  9073.        B. One of two functions that do 32-bit signed arithmetic without
  9074.        causing a runtime error on overflow. Normal arithmetic may cause a
  9075.        runtime error even if the arithmetic debugging switch is off. Both
  9076.        LMULOK and LADDOK return TRUE if there is no overflow, and FALSE if
  9077.        there is. These routines are useful for extended-precision
  9078.        arithmetic, or modulo 2^32 arithmetic, or arithmetic based on user
  9079.        input data.
  9080.  
  9081.  
  9082.  FUNCTION LN (X : REAL) : REAL;
  9083.  
  9084.        An arithmetic function. Returns the logarithm, base e, of X. Both X
  9085.        and the return value are of type REAL. To force a particular
  9086.        precision, declare LNSRQQ (CONSTS REAL4) and/or LNDRQQ (CONSTS REAL8)
  9087.        and use them instead. An error occurs if X is less than or equal to
  9088.        zero.
  9089.  
  9090.  
  9091.  FUNCTION LNSRQQ (CONSTS A : REAL4) : REAL4;
  9092.  FUNCTION LNDRQQ (CONSTS A : REAL8) : REAL8;
  9093.  
  9094.        See FUNCTION LN.
  9095.  
  9096.  
  9097.  FUNCTION LOBYTE (INTEGER-WORD) : BYTE;
  9098.  
  9099.        An extend level intrinsic function. Returns the least significant
  9100.        byte of an INTEGER or WORD. Depending on the target processor,
  9101.        the least significant byte may be the first or the second
  9102.        addressed byte of the word.
  9103.  
  9104.        See also FUNCTION HIBYTE.
  9105.  
  9106.  
  9107.  FUNCTION LOCKED (VARS SEMAPHORE : WORD) : BOOLEAN;
  9108.  
  9109.        A library function (semaphore). If the semaphore was available,
  9110.        LOCKED returns the value TRUE and sets the semaphore unavailable.
  9111.        Otherwise, if it was already locked, LOCKED returns FALSE. UNLOCK
  9112.        sets the semaphore available. As a binary semaphore, there are only
  9113.        two states.
  9114.  
  9115.        See also PROCEDURE UNLOCK.
  9116.  
  9117.  
  9118.  FUNCTION LOWER (EXPRESSION) : VALUE;
  9119.  
  9120.        An extend level intrinsic function. LOWER takes a single parameter
  9121.        of one of the following types: array, set, enumerated, or subrange.
  9122.        The value returned by LOWER is one of the following:
  9123.  
  9124.        1.  the lower bound of an array
  9125.  
  9126.        2.  the first allowable element of a set
  9127.  
  9128.        3.  the first value of an enumerated type
  9129.  
  9130.        4.  the lower bound of a subrange
  9131.  
  9132.        LOWER uses the type, not the value, of the expression. The value
  9133.        returned by LOWER is always a constant.
  9134.  
  9135.        See also FUNCTION UPPER.
  9136.  
  9137.  
  9138.  FUNCTION LOWORD (INTEGER4) : WORD;
  9139.  
  9140.        An extend level intrinsic function. Returns the low-order WORD
  9141.        of the four bytes of the INTEGER4.
  9142.  
  9143.        See also FUNCTION HIWORD.
  9144.  
  9145.  
  9146.  PROCEDURE MARKAS (VAR HEAPMARK : INTEGER4);
  9147.  
  9148.        A library procedure (heap management). Parallels the MARK procedure
  9149.        in other Pascals. MARKAS marks the upper and lower limits of the
  9150.        heap. The DISPOSE procedure is generally more powerful, but MARKAS
  9151.        may be useful for converting from other Pascal dialects.
  9152.  
  9153.        In other Pascals, the parameter is of a pointer type. However,
  9154.        MS-Pascal needs two words to save the heap limits, since in some
  9155.        implementations the heap grows toward both higher and lower
  9156.        addresses. The HEAPMARK variable should not be used as a normal
  9157.        INTEGER4 number; it should only be set by MARKAS and passed to
  9158.        RELEAS.
  9159.  
  9160.        To use MARKAS and RELEAS, pass an INTEGER4 variable, M for
  9161.        example, as a VAR parameter to MARKAS. MARKAS places the bounds of
  9162.        the heap in M. To release heap space, simply invoke the procedure
  9163.        with RELEAS (M).
  9164.  
  9165.        MARKAS and RELEAS work as intended only if you never call
  9166.        DISPOSE.
  9167.  
  9168.  
  9169.  FUNCTION MDSRQQ (CONSTS A, B : REAL4) : REAL4;
  9170.  FUNCTION MDDRQQ (CONSTS A, B : REAL8) : REAL8;
  9171.  
  9172.        Arithmetic functions. A modulo B, defined as:
  9173.  
  9174.        MDSRQQ (A, B) = A - AISRQQ (A/B) * B
  9175.        MDDRQQ (A, B) = A - AIDRQQ (A/B) * B
  9176.  
  9177.        Both A and B are of type REAL4 or REAL8, as shown. These
  9178.        functions are from the MS-FORTRAN runtime library and must be
  9179.        declared EXTERN before use.
  9180.  
  9181.  
  9182.  FUNCTION MEMAVL : WORD;
  9183.  
  9184.        A library functioqwn (heap management). Returns the number of
  9185.        bytes available between the stack and the heap. MEMAVL acts like the
  9186.        MEMAVAIL function in UCSD Pascal. If you have previously used
  9187.        DISPOSE, MEMAVL may return a value less than the actual number of
  9188.        bytes available.
  9189.  
  9190.  
  9191.  FUNCTION MNSRQQ (CONSTS A, B : REAL4) : REAL4;
  9192.  FUNCTION MNDRQQ (CONSTS A, B : REAL8) : REAL8;
  9193.  
  9194.        Arithmetic functions. Return the value of A or B, whichever is
  9195.        smaller. Both A and B are of type REAL4 or REAL8, as shown. These
  9196.        functions are from the MS-FORTRAN runtime library and must be
  9197.        declared EXTERN before use.
  9198.  
  9199.        See also FUNCTION MXSRQQ and FUNCTION MXDRQQ.
  9200.  
  9201.  
  9202.  PROCEDURE MOVEL (S, D : ADRMEM; N : WORD);
  9203.  
  9204.        A system level intrinsic procedure. Moves N characters (bytes)
  9205.        starting at S^ to D^, beginning with the lowest addressed byte of
  9206.        each array. Regardless of the value of the range and index checking
  9207.        switches, there is no bounds checking.
  9208.  
  9209.        Example:
  9210.  
  9211.            MOVEL (ADR 'New String Value', ADR V, 16)
  9212.  
  9213.        See also PROCEDURE MOVESL for segmented address types. Use
  9214.        MOVEL and MOVESL to shift bytes left or when the address ranges do
  9215.        not overlap.
  9216.  
  9217.        The MOVE and FILL procedures take value parameters of type
  9218.        ADRMEM and ADSMEM, but since all ADR (or ADS) types are compatible,
  9219.        the ADR (or ADS) of any variable or constant can be used as the
  9220.        actual parameter. These are dangerous but sometimes useful
  9221.        procedures.
  9222.  
  9223.  
  9224.  PROCEDURE MOVER (S, D : ADRMEM; N : WORD);
  9225.  
  9226.        A system level intrinsic procedure. Like MOVEL, but starts at the
  9227.        highest addressed byte of each array. Use MOVER and MOVESR to shift
  9228.        bytes right. As with MOVEL, there is no bounds checking.
  9229.  
  9230.        Example:
  9231.  
  9232.            MOVER (ADR V[0], ADR V[4], 12)
  9233.  
  9234.        See also PROCEDURE MOVESR for segmented address types.
  9235.  
  9236.        The MOVEs and FILLs  take value parameters of type ADRMEM and
  9237.        ADSMEM, but since all ADR (or ADS) types are compatible, the ADR (or
  9238.        ADS) of any variable or constant can be used as the actual parameter.
  9239.        These are dangerous but sometimes useful procedures.
  9240.  
  9241.  
  9242.  PROCEDURE MOVESL (S, D : ADSMEM; :N : WORD);
  9243.  
  9244.        A system level intrinsic procedure. Moves N characters (bytes)
  9245.        starting at S^ to D^, beginning with the lowest addressed byte of
  9246.        each array. Regardless of the value of the range and index checking
  9247.        switches, there is no bounds checking.
  9248.  
  9249.        Example:
  9250.  
  9251.            MOVESL (ADS 'New String Value', ADS V, 16)
  9252.  
  9253.        See also PROCEDURE MOVEL for relative address types. Use MOVEL
  9254.        and MOVESL to shift bytes left or when the address ranges do not
  9255.        overlap.
  9256.  
  9257.        The MOVE and FILL procedures take value parameters of type
  9258.        ADRMEM and ADSMEM, but since all ADR (or ADS) types are compatible,
  9259.        the ADR (or ADS) of any variable or constant can be used as the
  9260.        actual parameter. These are dangerous but sometimes useful
  9261.        procedures.
  9262.  
  9263.  
  9264.  PROCEDURE MOVESR (S, D : ADSMEM; N : WORD);
  9265.  
  9266.        A system level intrinsic procedure. Like MOVESL, but starts at the
  9267.        highest addressed byte of each array. Use MOVER and MOVESR to shift
  9268.        bytes right. As with MOVESL, there is no bounds checking.
  9269.  
  9270.        Example:
  9271.  
  9272.            MOVESR (ADS V[0], ADS V[4], 12)
  9273.  
  9274.        See also PROCEDURE MOVER for relative address types.
  9275.  
  9276.        The MOVE and FILL procedures take value parameters of type
  9277.        ADRMEM and ADSMEM, but since all ADR (or ADS) types are compatible,
  9278.        the ADR (or ADS) of any variable or constant can be used as the
  9279.        actual parameter. These are dangerous but sometimes useful
  9280.        procedures.
  9281.  
  9282.  
  9283.  FUNCTION MXSRQQ (CONSTS A, B : REAL4) : REAL4;
  9284.  FUNCTION MXDRQQ (CONSTS A, B : REAL8) : REAL8;
  9285.  
  9286.        Arithmetic functions. Return the value of A or B, whichever is
  9287.        larger. Both A and B are of type REAL4 or REAL8, as shown. These
  9288.        functions are from the MS-FORTRAN runtime library and must be
  9289.        declared EXTERN before use.
  9290.  
  9291.        See also FUNCTION MNSRQQ and MNDRQQ.
  9292.  
  9293.  
  9294.  PROCEDURE NEW (VARS P : POINTER);
  9295.  
  9296.        A library procedure (heap management, short form). Allocates a new
  9297.        variable V on the heap and at the same time assigns a pointer to V to
  9298.        the pointer variable P (a VARS parameter). The type of V is
  9299.        determined by the pointer declaration of P. If V is a super array
  9300.        type, use the long form of the procedure instead. If V is a record
  9301.        type with variants, the variants giving the largest possible size are
  9302.        assumed, permitting any variant to be assigned to P^.
  9303.  
  9304.  
  9305.  PROCEDURE NEW (VARS P : POINTER; T1, T2, ... TN : TAGS);
  9306.  
  9307.        A library procedure (heap management, long form). Allocates a
  9308.        variable with the variant specified by the tag field values T1
  9309.        through TN. The tag field values are listed in the order in which
  9310.        they are declared. Any trailing tag fields can be omitted.
  9311.  
  9312.        If all tag field values are constant, MS-Pascal allocates only
  9313.        the amount of space required on the heap, rounded up to a word
  9314.        boundary. The value of any omitted tag fields is assumed to be such
  9315.        that the maximum possible size is allocated.
  9316.  
  9317.        If some tag fields are not constant values, the compiler uses
  9318.        one of two strategies:
  9319.  
  9320.        1.  It assumes that the first nonconstant tag field and all
  9321.            following tags have unknown values, and allocates the maximum
  9322.            size necessary.
  9323.  
  9324.        2.  It generates a special runtime call to a function that
  9325.            calculates the record size from the variable tag values
  9326.            available. This depends on the implementation. A similar
  9327.            procedure applies to DISPOSE and SIZEOF.
  9328.  
  9329.        You should set all tag fields to their proper values after the
  9330.        call to NEW and never change them. The compiler does not do any of
  9331.        the following:
  9332.  
  9333.        1.  assign tag values
  9334.  
  9335.        2.  check that they are initialized correctly
  9336.  
  9337.        3.  check that their value is not changed during execution
  9338.  
  9339.        According to the ISO standard, a variable created with the long
  9340.        form of NEW cannot be any of the following:
  9341.  
  9342.        1.  used as an expression operand
  9343.  
  9344.        2.  passed as a parameter
  9345.  
  9346.        3.  assigned a value
  9347.  
  9348.        MS-Pascal does not catch these errors. Fields within the record
  9349.        can be used normally.
  9350.  
  9351.        Assigning a larger record to a smaller one allocated with the
  9352.        long form of NEW would wipe out part of the heap. This condition is
  9353.        difficult to detect at compile time. Therefore, in MS-Pascal, any
  9354.        assignment to a record in the heap that has variants uses the actual
  9355.        length of the record in the heap, rather than the maximum length.
  9356.  
  9357.        However, an assignment to a field in an invalid variant may
  9358.        destroy part of another heap variable or the heap structure itself.
  9359.        This error is not caught, unless all tag values are explicit, the tag
  9360.        values are correct, and the tag checking switch is on.
  9361.  
  9362.        The extend level allows pointers to super arrays. The long form
  9363.        form of NEW is used as described above, except that array upper bound
  9364.        values are given instead of tag values. All upper bounds must be
  9365.        given. Bounds can be constants or expressions; in any case, only the
  9366.        size required is allocated.
  9367.  
  9368.        The entire array referenced by such a pointer cannot be assigned
  9369.        or compared, except that LSTRINGs can always be compared. The entire
  9370.        array can be passed as a reference parameter if the formal parameter
  9371.        is of the same super array type. Components of the array can be used
  9372.        normally.
  9373.  
  9374.  
  9375.  FUNCTION ODD (X : ORDINAL) : BOOLEAN;
  9376.  
  9377.        A data conversion function. Tests the ordinal value X to see whether
  9378.        it is odd. ODD is TRUE only if ORD (X) is odd; otherwise it is
  9379.        FALSE.
  9380.  
  9381.  
  9382.  FUNCTION ORD (X : VALUE) : INTEGER;
  9383.  
  9384.        A data conversion function. Converts to INTEGER any value of one
  9385.        of the types shown in the following list according to the rules
  9386.        given.
  9387.  
  9388.        Type of X        Return value
  9389.        ─────────────────────────────────────────────────────────────────────
  9390.        INTEGER          X
  9391.  
  9392.        WORD <= MAXINT   X
  9393.  
  9394.        WORD >  MAXINT   X - 2 * (MAXINT + 1)
  9395.                         (i.e., same 16 bits
  9396.                         as at start!)
  9397.  
  9398.        CHAR             ASCII code for X
  9399.  
  9400.        Enumerated       Position of X in the
  9401.                         type definition,
  9402.                         starting with 0
  9403.  
  9404.        INTEGER4         Lower 16 bits
  9405.                         (i.e., same as
  9406.                         ORD (LOWORD (INTEGER4))
  9407.  
  9408.        Pointer          Integer value of
  9409.                         pointer
  9410.  
  9411.  
  9412.  PROCEDURE PACK(CONSTS A : UNPACKED;
  9413.  I : INDEX; VARS Z : PACKED);
  9414.  
  9415.        A data conversion procedure. Moves elements of an unpacked array to a
  9416.        packed array. If A is an ARRAY [M..N] OF T and Z is a PACKED ARRAY
  9417.        [U..V] OF T, then PACK (A, I, Z) is the same as:
  9418.  
  9419.        FOR J := U TO V DO Z [J] := A [J - U + I]
  9420.  
  9421.        In both PACK and UNPACK, the parameter I is the initial index
  9422.        within A. The bounds of the arrays and the value of I must be
  9423.        reasonable; i.e., the number of components in the unpacked array A
  9424.        from I to M must be at least as great as the number of components in
  9425.        the packed array Z. The range checking switch controls checking of
  9426.        the bounds.
  9427.  
  9428.  
  9429.  PROCEDURE PAGE;
  9430.  PROCEDURE PAGE (VAR F);
  9431.  
  9432.        A file system procedure. Causes skipping to the top of a new page
  9433.        when the textfile F is printed. PAGE with no parameter is the same
  9434.        as PAGE (INPUT).
  9435.  
  9436.        See Section 16.1.4, "PAGE," for a description of PAGE.
  9437.  
  9438.  
  9439.  FUNCTION PISRQQ
  9440.  (CONSTS A : REAL4; CONSTS B : INTEGER4) : REAL4;
  9441.  FUNCTION PIDRQQ
  9442.  (CONSTS A : REAL8; CONSTS B : INTEGER4) : REAL8;
  9443.  
  9444.        Arithmetic functions. The return value is A**B (A to the INTEGER
  9445.        power of B). A is of type REAL4 or REAL8, as shown. B is always of
  9446.        type INTEGER4. These functions are from the MS-FORTRAN runtime
  9447.        library and must be declared EXTERN before use.
  9448.  
  9449.  
  9450.  PROCEDURE PLYUQQ;
  9451.  
  9452.        A library routine (terminal I/O). Writes an end-of-line
  9453.        character to the terminal screen.
  9454.  
  9455.        Together with GETYQQ and PTYUQQ, PLYUQQ is useful for doing
  9456.        terminal I/O in a low-overhead environment. These functions are part
  9457.        of a collection of routines called Unit U, which implements the
  9458.        MS-Pascal file system. (See Section 10.2, "An Overview of the File
  9459.        System," in your Microsoft Pascal Compiler User's Guide for further
  9460.        information on Unit U.)
  9461.  
  9462.  
  9463.  FUNCTION POSITN
  9464.  (CONSTS PAT : STRING; CONSTS S : STRING; I : INTEGER) : INTEGER;
  9465.  
  9466.        A string intrinsic function. Returns the integer position of the
  9467.        pattern PAT in S, starting the search at S [I]. If PAT is not found
  9468.        or if I > upper (S), the return value is 0. If PAT is the null
  9469.        string, the return value is 1. There are no error conditions.
  9470.  
  9471.  
  9472.  FUNCTION PRED (X : ORDINAL) : ORDINAL;
  9473.  
  9474.        A data conversion function. Determines the ordinal "predecessor" to
  9475.        X. The ORD of the result returned is equal to ORD (X) - 1. An error
  9476.        occurs if the predecessor is out of range or overflow occurs. These
  9477.        errors are caught if appropriate debug switches are on.
  9478.  
  9479.  
  9480.  FUNCTION PRSRQQ (A, B : REAL4) : REAL4;
  9481.  FUNCTION PRDRQQ (A, B : REAL8) : REAL8;
  9482.  
  9483.        Arithmetic functions. The return value is A**B (A to the REAL power
  9484.        of B). Both A and B are of type REAL4 or REAL8, as shown. An error
  9485.        occurs if A < 0 (even if B happens to have an integer value). These
  9486.        functions are from the MS-FORTRAN runtime library and must be
  9487.        declared EXTERN before use.
  9488.  
  9489.  
  9490.  PROCEDURE PTYUQQ (LEN : WORD; LOC : ADSMEM);
  9491.  
  9492.        A library routine (terminal I/O). Writes LEN characters,
  9493.        beginning at LOC in memory, to the terminal screen.
  9494.  
  9495.        Example:
  9496.  
  9497.            PTYUQQ (8, ADS 'PROMPT:');
  9498.  
  9499.        Together with GETYQQ and PLYUQQ, PTYUQQ is useful for doing
  9500.        terminal I/O in a low-overhead environment. These functions are part
  9501.        of a collection of routines called Unit U, which implements the
  9502.        MS-Pascal file system. (See Section 10.2, "An Overview of the File
  9503.        System," in your Microsoft Pascal Compiler User's Guide for further
  9504.        information on Unit U.)
  9505.  
  9506.  
  9507.  PROCEDURE PUT (VAR F);
  9508.  
  9509.        A file system procedure. Writes the value of the file buffer
  9510.        variable F^ to the currently pointed-to component of F and advances
  9511.        the file pointer.
  9512.  
  9513.        See Section 16.1.1, "GET and PUT," for a description of PUT.
  9514.  
  9515.  
  9516.  PROCEDURE READ (VAR F; P1, P2, ... CR);
  9517.  
  9518.        A file system procedure. READ reads data from files. Both READ and
  9519.        READLN are defined in terms of the more primitive operation, GET.
  9520.  
  9521.        See Section 16.2, "Textfile Input and Output," for a description
  9522.        of READ.
  9523.  
  9524.  
  9525.  PROCEDURE READFN (VAR F; P1, P2, ... CR);
  9526.  
  9527.        A file system procedure (extend level I/O). READFN is the same
  9528.        as READ (not READLN) with two exceptions:
  9529.  
  9530.        1.  File parameter F should be present (INPUT is assumed but a
  9531.            warning is given).
  9532.  
  9533.        2.  If a parameter P is of type FILE, a sequence of characters
  9534.            forming a valid filename is read from F and assigned to P in
  9535.            the same manner as ASSIGN.
  9536.  
  9537.        Parameters of other types are read in the same way as the READ
  9538.        procedure.
  9539.  
  9540.        See Section 16.3.1, "Extend Level Procedures," for a description
  9541.        of READFN.
  9542.  
  9543.  
  9544.  PROCEDURE READLN (VAR F; P1, P2, ... CR);
  9545.  
  9546.        A textfile I/O procedure. At the primitive GET level, without
  9547.        parameters, READLN (F) is equivalent to the following:
  9548.  
  9549.           BEGIN
  9550.             WHILE NOT EOLN (F) DO GET (F);
  9551.             GET (F)
  9552.           END
  9553.  
  9554.        The procedure READLN is very much like READ, except that it reads up
  9555.        to and including the end of line.
  9556.  
  9557.        See Section 16.2, "Textfile Input and Output," for a description
  9558.        of READ.
  9559.  
  9560.  
  9561.  PROCEDURE READSET
  9562.  (VAR F; VAR L : LSTRING; CONST S : SETOFCHAR);
  9563.  
  9564.        A file system procedure (extend level I/O). READSET reads characters
  9565.        and puts them into L, as long as the characters are in the set S and
  9566.        there is room in L.
  9567.  
  9568.        See Section 16.3.1, "Extend Level Procedures," for a description
  9569.        of READSET.
  9570.  
  9571.  
  9572.  PROCEDURE RELEAS (VAR HEAPMARK : INTEGER4);
  9573.  
  9574.        A library routine (heap management). Parallels the RELEASE procedure
  9575.        in other Pascals. RELEAS disposes of heap space past the area set
  9576.        with a previous MARKAS call. The DISPOSE procedure in MS-Pascal is
  9577.        generally more powerful, but RELEAS may be useful for converting from
  9578.        other Pascal dialects.
  9579.  
  9580.        In other Pascals, the parameter is of a pointer type. However,
  9581.        MS-Pascal needs two words to save the heap limits, since in some
  9582.        implementations the heap grows toward both higher and lower
  9583.        addresses. The HEAPMARK variable should not be used as a normal
  9584.        INTEGER4 number;  it should only be set by MARKAS and passed to
  9585.        RELEAS.
  9586.  
  9587.        To use MARKAS and RELEAS, pass an INTEGER4 variable, M for
  9588.        example, as a VAR parameter to MARKAS. MARKAS places the bounds of
  9589.        the heap in M. To RELEAS heap space, simply invoke the procedure
  9590.        with RELEAS (M).
  9591.  
  9592.        MARKAS and RELEAS work as intended only if DISPOSE is never
  9593.        called.
  9594.  
  9595.  
  9596.  PROCEDURE RESET (VAR F);
  9597.  
  9598.        A file system procedure. Resets the current file position to its
  9599.        beginning and does a GET (F).
  9600.  
  9601.        See Section 16.1.2, "RESET and REWRITE," for a description of
  9602.        RESET.
  9603.  
  9604.  
  9605.  FUNCTION RESULT (FUNCTION-IDENTIFIER) : VALUE;
  9606.  
  9607.        An extend level intrinsic function. Used to access the current
  9608.        value of a function; can only be used within the body of the function
  9609.        itself or in a procedure or function nested within it.
  9610.  
  9611.  
  9612.  FUNCTION RETYPE (TYPE-IDENT, EXPRESSION) : TYPE-IDENT;
  9613.  
  9614.        A system level intrinsic function. Provides a generic type escape,
  9615.        returns the value of the given expression as if it had the type named
  9616.        by the type identifier. The types implied by the type identifier and
  9617.        the expression should usually have the same length, but this is not
  9618.        required. RETYPE for a structure can be followed by component
  9619.        selectors (array index, fields, reference, etc.). RETYPE is a
  9620.        "dangerous" type escape and may not work as intended.
  9621.  
  9622.        Example:
  9623.  
  9624.            TYPE COLOR = (RED, BLUE, GREEN);
  9625.                 S2    = STRING (2);
  9626.            VAR C :CHAR;
  9627.                I, J :INTEGER;
  9628.                R :REAL4;
  9629.                TINT :
  9630.            COLOR;
  9631.                .
  9632.                .
  9633.                R := RETYPE (REAL4, 'abcd');
  9634.                {Here, a 4-byte string literal is}
  9635.                {converted into a real number.}
  9636.                {Note that REAL4 numbers also}
  9637.                {require 4 bytes.}
  9638.  
  9639.                TINT := RETYPE (COLOR, 2)
  9640.                {Here, 2 is converted into a color,}
  9641.                {which in this case is GREEN.}
  9642.                {This is a relatively "safe" use}
  9643.                {of the RETYPE function.}
  9644.  
  9645.                C := RETYPE (S2, I) [J]
  9646.                {Here, I is retyped into a two}
  9647.                {character string. Then J selects}
  9648.                {a single character of the string}
  9649.                {which is assigned to C.}
  9650.  
  9651.  
  9652.        There are two other ways to change type in MS-Pascal.
  9653.  
  9654.        1.  First, you can declare a record with one variant of each type
  9655.            needed, assign an expression to one variant, and then get the
  9656.            value back from another variant.  (This is an error not
  9657.            caught at the standard level. Note that the relative mapping
  9658.            of variables is subject to change between different versions
  9659.            of the compiler.)
  9660.  
  9661.        2.  Second, you can declare an address variable of the type
  9662.            wanted and assign to it the address of any other variable
  9663.            (using ADR).
  9664.  
  9665.        Each of these methods has its own subtle differences and quirks
  9666.        and should be avoided whenever possible.
  9667.  
  9668.  
  9669.  PROCEDURE REWRITE (F);
  9670.  
  9671.        A file system procedure. Resets the current file position to its
  9672.        beginning.
  9673.  
  9674.        See Section 16.1.2, "RESET and REWRITE," for a description of
  9675.        REWRITE.
  9676.  
  9677.  
  9678.  FUNCTION ROUND (X : REAL) : INTEGER;
  9679.  
  9680.        An arithmetic function. Rounds X away from zero. X is of type
  9681.        REAL4 or REAL8; the return value is of type INTEGER. The effect of
  9682.        ROUND on a number with a fractional part of 0.5 varies with the
  9683.        implementation.
  9684.  
  9685.        Examples:
  9686.  
  9687.        ROUND (1.6) is 2
  9688.        ROUND (-1.6) is -2
  9689.  
  9690.        An error occurs if ABS (X + 0.5) >= MAXINT.
  9691.  
  9692.  
  9693.  FUNCTION ROUND4 (X : REAL) : INTEGER4;
  9694.  
  9695.        An arithmetic function. Rounds real X away from zero. X is of
  9696.        type REAL4 or REAL8; the return value is of type INTEGER4. The
  9697.        effect of ROUND4 on a number with a fractional part of 0.5 varies
  9698.        with the implementation.
  9699.  
  9700.        Examples:
  9701.  
  9702.        ROUND4 (1.6) is 2
  9703.        ROUND4 (-1.6) is -2
  9704.  
  9705.        An error occurs if ABS (X + 0.5) >= MAXINT4.
  9706.  
  9707.  
  9708.  FUNCTION SADDOK
  9709.  (A, B : INTEGER; VAR C : INTEGER) : BOOLEAN;
  9710.  
  9711.        A library routine (no-overflow arithmetic). Sets C equal to A
  9712.        plus B. One of two functions that do 16-bit signed arithmetic
  9713.        without causing a runtime error on overflow. Normal arithmetic may
  9714.        cause a runtime error even if the arithmetic debugging switch is off.
  9715.        Both SADDOK and SMULOK return TRUE if there is no overflow, and FALSE
  9716.        if there is. These routines can be useful for extended-precision
  9717.        arithmetic, or modulo 2^16 arithmetic, or arithmetic based on user
  9718.        input data.
  9719.  
  9720.  
  9721.  FUNCTION SCANEQ (LEN : INTEGER; PAT : CHAR;
  9722.  CONSTS S : STRING; I : INTEGER) : INTEGER;
  9723.  
  9724.        A string intrinsic function. Scans, starting at S [I], and
  9725.        returns the number of characters skipped. SCANEQ stops scanning when
  9726.        a character equal to pattern PAT is found or LEN characters have been
  9727.        skipped. If LEN < 0, SCANEQ scans backwards and returns a negative
  9728.        number. SCANEQ returns the LEN parameter if it finds no characters
  9729.        equal to pattern PAT found or if I > UPPER (S). There are no error
  9730.        conditions.
  9731.  
  9732.  
  9733.  FUNCTION SCANNE (LEN : INTEGER; PAT : CHAR;
  9734.  CONSTS S : STRING; I : INTEGER) : INTEGER;
  9735.  
  9736.        A string intrinsic function. Like SCANEQ, but stops scanning
  9737.        when a character not equal to pattern PAT is found.
  9738.  
  9739.        SCANNE stops scanning when a character not equal to pattern PAT is
  9740.        found or LEN characters have been skipped. If LEN < 0, SCANNE scans
  9741.        backwards and returns a negative number. SCANNE returns LEN
  9742.        parameter if it finds all characters equal to pattern PAT found or if
  9743.        I > UPPER (S). There are no error conditions.
  9744.  
  9745.  
  9746.  PROCEDURE SEEK (VAR F; N : INTEGER4);
  9747.  
  9748.        A file system procedure (extend level I/O). In contrast to normal
  9749.        sequential files, DIRECT files are random access structures. SEEK is
  9750.        used to randomly access components of such files.
  9751.  
  9752.  
  9753.  FUNCTION SHSRQQ (CONSTS A : REAL4) : REAL4;
  9754.  FUNCTION SHDRQQ (CONSTS A : REAL8) : REAL8;
  9755.  
  9756.        Arithmetic functions. Return the hyperbolic sine of A. A is of type
  9757.        REAL4 or REAL8, as shown. These functions are from the MS-FORTRAN
  9758.        runtime library and must be declared EXTERN before use.
  9759.  
  9760.  
  9761.  FUNCTION SIN (X : NUMERIC) : REAL;
  9762.  
  9763.        An arithmetic function. Returns the sine of X in radians. Both X and
  9764.        the return value are of type REAL. To force a particular precision,
  9765.        declare SNSRQQ (CONSTS REAL4) and/or SNDRQQ (CONSTS REAL8) and use
  9766.        them instead.
  9767.  
  9768.  
  9769.  FUNCTION SIZEOF (VARIABLE) : WORD;
  9770.  FUNCTION SIZEOF (VARIABLE, TAG1,
  9771.  TAG2, ... TAGN) : WORD;
  9772.  
  9773.        An extend level intrinsic function. Returns the size of a variable
  9774.        in bytes. Tag values or array upper bounds are set as in
  9775.        the NEW and DISPOSE functions. If the variable is a record with
  9776.        variants, and the first form is used, the maximum size possible is
  9777.        returned. If the variable is a super array, the second form, which
  9778.        gives upper bounds, must be used.
  9779.  
  9780.  
  9781.  FUNCTION SMULOK
  9782.  (A, B : INTEGER; VAR C : INTEGER) : BOOLEAN;
  9783.  
  9784.        A library routine (no-overflow arithmetic function). Sets C equal to
  9785.        A times B. One of two functions that do 16-bit signed arithmetic
  9786.        without causing a runtime error on overflow. Normal arithmetic may
  9787.        cause a runtime error, even if the arithmetic debugging switch is
  9788.        off. Each routine returns TRUE if there is no overflow, and FALSE if
  9789.        there is. These routines can be useful for extended-precision
  9790.        arithmetic, or modulo 2^16 arithmetic, or arithmetic based on user
  9791.        input data.
  9792.  
  9793.  
  9794.  FUNCTION SNSRQQ (CONSTS A : REAL4) : REAL4;
  9795.  FUNCTION SNDRQQ (CONSTS A : REAL8) : REAL8;
  9796.  
  9797.        See Function SIN.
  9798.  
  9799.  
  9800.  FUNCTION SQR (X : NUMERIC) : NUMERIC;
  9801.  
  9802.        An arithmetic function. Returns the square of X, where X is of
  9803.        type REAL, INTEGER, WORD, or INTEGER4.
  9804.  
  9805.  
  9806.  FUNCTION SQRT (X) : REAL
  9807.  
  9808.        An arithmetic function. Returns the square root of X, where X is
  9809.        of type REAL. To force a particular precision, declare SRSRQQ
  9810.        (CONSTS REAL4) and/or SRDRQQ (CONSTS REAL8) and use them instead. An
  9811.        error occurs if X is less than 0.
  9812.  
  9813.  
  9814.  FUNCTION SRSRQQ (CONSTS A : REAL4) : REAL4;
  9815.  FUNCTION SRDRQQ (CONSTS A : REAL8) : REAL8;
  9816.  
  9817.        See also Function SQRT.
  9818.  
  9819.  
  9820.  FUNCTION SUCC (X : ORDINAL) : ORDINAL;
  9821.  
  9822.        A data conversion function. Determines the ordinal "successor" to X.
  9823.        The ORD of the returned result is equal to ORD (X) + 1. An error
  9824.        occurs if the successor is out of range or overflow occurs. These
  9825.        errors are caught if appropriate debug switches are on.
  9826.  
  9827.  
  9828.  FUNCTION THSRQQ (CONSTS A : REAL4) : REAL4;
  9829.  FUNCTION THDRQQ (CONSTS A : REAL8) : REAL8;
  9830.  
  9831.        Arithmetic functions. Return the hyperbolic tangent of A. Both A and
  9832.        the return value are of type REAL4 or REAL8, as shown. These
  9833.        functions are from the MS-FORTRAN runtime library and must be
  9834.        declared EXTERN before use.
  9835.  
  9836.  
  9837.  FUNCTION TICS : WORD;
  9838.  
  9839.        A library routine (clock function). If available, TICS returns
  9840.        the value of an operating system timing location. The result is in a
  9841.        time interval, such as hundredths of a second, depending on the
  9842.        target operating system.
  9843.  
  9844.  
  9845.  PROCEDURE TIME (VAR S : STRING);
  9846.  
  9847.        A library routine (clock function). If available, this procedure
  9848.        assigns the current time to its STRING (or LSTRING) variable. If the
  9849.        parameter is an LSTRING, you must set the length before you call the
  9850.        TIME procedure. The format depends on the target operating system.
  9851.  
  9852.        See also PROCEDURE DATE.
  9853.  
  9854.  
  9855.  FUNCTION TNSRQQ (CONSTS A : REAL4) : REAL4;
  9856.  FUNCTION TNDRQQ (CONSTS A : REAL8) : REAL8;
  9857.  
  9858.        Arithmetic functions. Return the tangent of A. Both A and the return
  9859.        value are of type REAL4 or REAL8, as shown. These functions are from
  9860.        the MS-FORTRAN runtime library and must be declared EXTERN before
  9861.        use.
  9862.  
  9863.  
  9864.  FUNCTION TRUNC (X : REAL) : INTEGER;
  9865.  
  9866.        An arithmetic function. Truncates X toward zero. X is of type
  9867.        REAL4 or REAL8, and the return value is of type INTEGER.
  9868.  
  9869.           TRUNC (1.6) is 1
  9870.           TRUNC (-1.6) is -1
  9871.  
  9872.        An error occurs if ABS (X - 1.0) >= MAXINT.
  9873.  
  9874.  
  9875.  FUNCTION TRUNC4 (X : REAL) : INTEGER4;
  9876.  
  9877.        An arithmetic function. Truncates real X toward zero. X is of
  9878.        type REAL4 or REAL8, and the return value is of type INTEGER4.
  9879.  
  9880.           TRUNC4 (1.6) is 1
  9881.           TRUNC4 (-1.6) is -1
  9882.  
  9883.        An error occurs if ABS (X - 1.0) >= MAXINT4.
  9884.  
  9885.  
  9886.  FUNCTION UADDOK (A, B : WORD; VAR C : WORD) : BOOLEAN;
  9887.  
  9888.        A library routine (no-overflow arithmetic function). Sets C equal to
  9889.        A plus B. One of two functions that do 16-bit unsigned arithmetic
  9890.        without causing a runtime error on overflow. Normal arithmetic may
  9891.        cause a runtime error even if the arithmetic debugging switch is off.
  9892.        The following is the binary carry resulting from this addition of A
  9893.        and B:
  9894.  
  9895.           WRD (NOT UADDOK (A, B, C))
  9896.  
  9897.        Both UADDOK and UMULOK return TRUE if there is no overflow and FALSE
  9898.        if there is. These routines are useful for extended-precision
  9899.        arithmetic, or modulo 2^16 arithmetic, or arithmetic based on user
  9900.        input data.
  9901.  
  9902.  
  9903.  FUNCTION UMULOK (A, B : WORD; VAR C : WORD) : BOOLEAN;
  9904.  
  9905.        A library routine (no-overflow arithmetic function). Sets C equal to
  9906.        A times B. One of two functions that do 16-bit unsigned arithmetic
  9907.        without causing a runtime error on overflow. Normal arithmetic may
  9908.        cause a runtime error even if the arithmetic debugging switch is off.
  9909.        Each routine returns TRUE if there is no overflow and FALSE if there
  9910.        is. These routines are useful for extended-precision arithmetic, or
  9911.        modulo 2^16 arithmetic, or arithmetic based on user input data.
  9912.  
  9913.  
  9914.  PROCEDURE UNLOCK (VARS SEMAPHORE : WORD);
  9915.  
  9916.        A library routine (semaphore procedure). UNLOCK sets the
  9917.        semaphore available. As a binary semaphore, there are only two
  9918.        states. UNLOCK can be called any number of times and can be used to
  9919.        initialize the semaphore.
  9920.  
  9921.        See also FUNCTION LOCKED.
  9922.  
  9923.  
  9924.  PROCEDURE UNPACK
  9925.  (CONSTS Z : PACKED; VARS A : UNPACKED; I : INDEX);
  9926.  
  9927.        A data conversion procedure. Moves elements from packed array to an
  9928.        unpacked array. If A is an ARRAY [M..N] OF T, and Z is a PACKED
  9929.        ARRAY [U..V] OF T then the above call is the same as:
  9930.  
  9931.           FOR J := U TO V DO A [J - U + I] := Z [J]
  9932.  
  9933.        In both PACK and UNPACK, the parameter I is the initial index within
  9934.        A. The bounds of the arrays and the value of I must be reasonable;
  9935.        i.e., the number of components in the unpacked array A from I to M
  9936.        must be at least as great as the number of components in the packed
  9937.        array Z. The range checking switch controls checking of the bounds.
  9938.  
  9939.        See also PROCEDURE PACK
  9940.  
  9941.  
  9942.  FUNCTION UPPER (EXPRESSION) : VALUE;
  9943.  
  9944.        An extend level intrinsic function. UPPER, like LOWER, takes a
  9945.        single parameter of one of the following types: array, set,
  9946.        enumerated, or subrange. The value returned by UPPER is one of the
  9947.        following:
  9948.  
  9949.        1.  the upper bound of an array
  9950.  
  9951.        2.  the last allowable element of a set
  9952.  
  9953.        3.  the last value of an enumerated type
  9954.  
  9955.        4.  the upper bound of a subrange
  9956.  
  9957.        The value returned by UPPER is always a constant, unless the
  9958.        expression is of a super array type. In this case, the actual upper
  9959.        bound of the super array type is returned. Note that the type and
  9960.        not the value of the expression is used for UPPER.
  9961.  
  9962.        See also FUNCTION LOWER.
  9963.  
  9964.  
  9965.  PROCEDURE VECTIN (V : WORD; PROCEDURE I [INTERRUPT]);
  9966.  
  9967.        A library routine (interrupt handling procedure). One of three
  9968.        procedures for processing interrupts. VECTIN sets an interrupt
  9969.        vector, so that interrupts of type V are connected to procedure I.
  9970.        (ENABIN enables interrupts and DISBIN disables interrupts.) The
  9971.        effect of these procedures and the meaning of V varies with the
  9972.        target machine. See Appendix B, "Version Specifics," in the
  9973.        Microsoft Pascal Compiler User's Guide for information regarding your
  9974.        implementation.
  9975.  
  9976.  
  9977.  FUNCTION WRD (X : VALUE) : WORD;
  9978.  
  9979.        A data conversion procedure. Converts to WORD any of the types shown
  9980.        in the following list according to the rules given.
  9981.  
  9982.            Type of X      Return Value
  9983.            ─────────────────────────────────────────────────────────────────
  9984.            WORD           X
  9985.  
  9986.            INTEGER >= 0   X
  9987.  
  9988.            INTEGER < 0    X + MAXWORD + 1
  9989.                           (i.e., same 16 bits
  9990.                           as at start!)
  9991.  
  9992.            CHAR           ASCII code for X
  9993.  
  9994.            Enumerated     Position of X in the
  9995.                           type definition,
  9996.                           starting with 0
  9997.  
  9998.            INTEGER4       Lower 16 bits
  9999.                           (i.e., same as
  10000.                           LOWORD(INTEGER4))
  10001.  
  10002.            Pointer        Word value of pointer
  10003.  
  10004.  
  10005.  PROCEDURE WRITE (VAR F; P1, P2, ... CR);
  10006.  PROCEDURE WRITELN (VAR F; P1, P2, ... CR);
  10007.  
  10008.        File system level intrinsic procedures. WRITEs data to files.
  10009.        WRITE and WRITELN are defined in terms of the more primitive
  10010.        operation PUT. WRITELN is the same as WRITE, except it also writes
  10011.        an end-of-line.
  10012.  
  10013.        See Section 16.2.3, "WRITE and WRITELN," for descriptions of
  10014.        these procedures.
  10015.  
  10016.  
  10017.  
  10018.  Chapter 16  File-Oriented Procedures and Functions
  10019.  
  10020.  ───────────────────────────────────────────────────────────────────────────
  10021.  
  10022.  16.1  File System Primitive Procedures and Functions
  10023.  
  10024.         16.1.1  GET and PUT
  10025.  
  10026.         16.1.2  RESET and REWRITE
  10027.  
  10028.         16.1.3  EOF and EOLN
  10029.  
  10030.         16.1.4  PAGE
  10031.  
  10032.         16.1.5  Lazy Evaluation
  10033.  
  10034.         16.1.6  Concurrent I/O
  10035.  
  10036.  16.2  Textfile Input and Output
  10037.  
  10038.         16.2.1  READ and READLN
  10039.  
  10040.         16.2.2  READ Formats
  10041.  
  10042.         16.2.3  WRITE and WRITELN
  10043.  
  10044.         16.2.4  WRITE Formats
  10045.  
  10046.  16.3  Extend Level I/O
  10047.  
  10048.         16.3.1  Extend Level Procedures
  10049.  
  10050.         16.3.2  Temporary Files
  10051.  
  10052.  
  10053.  
  10054.  Chapter 14, "Introduction to Procedures and Functions," introduced you to
  10055.  procedures and functions in general and described their use and
  10056.  construction.
  10057.  
  10058.  Chapter 15, "Available Procedures and Functions," described eight
  10059.  categories of procedures and functions that are available to you either
  10060.  because they are predeclared or because they are part of the Microsoft
  10061.  Pascal runtime libraries. All except those that relate to file input and
  10062.  output were discussed in detail.
  10063.  
  10064.  This chapter, Chapter 16, "File-Oriented Procedures and Functions,"
  10065.  discusses all of the file I/O procedures and functions, as well as lazy
  10066.  evaluation and concurrent I/O, two special MS-Pascal features that
  10067.  facilitate your use of files.
  10068.  
  10069.  The MS-Pascal file system supports a variety of procedures and
  10070.  functions that operate on files of different modes and structures.  These
  10071.  procedures and functions can be categorized as shown in Table 16.1.
  10072.  
  10073.  
  10074.  Table 16.1
  10075.  File System Procedures and Functions
  10076. ╓┌──────────────┌────────────┌───────────────────────────────────────────────╖
  10077.  Category       Procedures   Functions
  10078.  ───────────────────────────────────────────────────────────────────────────
  10079.  Primitive      GET          EOF
  10080.                 PAGE         EOLN
  10081.                 PUT
  10082.  Category       Procedures   Functions
  10083.                PUT
  10084.                 RESET
  10085.                 REWRITE
  10086.  
  10087.  Textfile I/O   READ
  10088.                 READLN
  10089.                 WRITE
  10090.                 WRITELN
  10091.  
  10092.  Extend         ASSIGN
  10093.  Level I/O      CLOSE
  10094.                 DISCARD
  10095.                 READSET
  10096.                 READFN
  10097.                 SEEK
  10098.  
  10099.  
  10100.  16.1  File System Primitive Procedures and Functions
  10101.  
  10102.  
  10103.  This section describes the seven primitive file system procedures and
  10104.  functions, which perform file I/O at the most basic level.  Later,
  10105.  descriptions of READ and WRITE procedures are defined in terms of the
  10106.  primitives GET and  PUT. Two related topics are also discussed in this
  10107.  section: lazy evaluation and concurrent I/O.  In all descriptions which
  10108.  follow, F is a file parameter (files are always reference parameters), and
  10109.  F^ is the buffer variable.
  10110.  
  10111.  In a segmented environment, all file variables operated on by these
  10112.  procedures must reside in the default data segment. This restriction
  10113.  increases the efficiency of file system calls.
  10114.  
  10115.      1.  GET and PUT
  10116.  
  10117.          The primitive procedures GET and PUT read to and write from
  10118.          the buffer variable F^.  GET assigns the next component of a file
  10119.          to the buffer variable. PUT performs the inverse operation and
  10120.          writes the value of the buffer variable to the next component of
  10121.          the file F.
  10122.  
  10123.      2.  RESET and REWRITE
  10124.  
  10125.          The procedures RESET and REWRITE set the current position of a
  10126.          file to its beginning. RESET prepares for later GET and READ
  10127.          procedures.  REWRITE prepares for later PUT and WRITE procedures.
  10128.  
  10129.      3.  EOF and EOLN
  10130.  
  10131.          The functions EOF and EOLN are used to check for the end-of-
  10132.          file and end-of-line conditions. They return a BOOLEAN result. In
  10133.          general, these values indicate when to stop reading a line or a
  10134.          file.
  10135.  
  10136.      4.  PAGE
  10137.  
  10138.          The procedure PAGE helps in formatting textfiles.  It is not a
  10139.          necessary procedure in the same sense as GET and PUT.
  10140.  
  10141.  
  10142.  16.1.1  GET and PUT
  10143.  
  10144.  
  10145.  The primitive procedures GET and PUT are used to read to and write from the
  10146.  buffer variable, F^.  GET assigns the next component of a file to the
  10147.  buffer variable. PUT performs the inverse operation and writes the value of
  10148.  the buffer variable to the next component of the file F.
  10149.  
  10150.  
  10151.  PROCEDURE GET (VAR F);
  10152.  
  10153.        A primitive file system intrinsic procedure. If there is a next
  10154.        component in the file F, then:
  10155.  
  10156.        1.  The current file position is advanced to the next component.
  10157.  
  10158.        2.  The value of this component is assigned to the buffer
  10159.            variable F^.
  10160.  
  10161.        3.  EOF (F) becomes FALSE.
  10162.  
  10163.        Advancing and assigning may be deferred internally, depending on
  10164.        the mode of the file.
  10165.  
  10166.        If no next component exists, then EOF (F) becomes TRUE and the
  10167.        value of F^ becomes undefined.  EOF (F) must be FALSE before GET (F),
  10168.        since reading past the end of file produces a runtime error. However,
  10169.        if F has mode DIRECT, EOF (F) can be TRUE or FALSE, since DIRECT mode
  10170.        permits repeated GET operations at the end of the file.  If F^ is a
  10171.        record with variants, the compiler reads the variant with the maximum
  10172.        size.
  10173.  
  10174.  
  10175.  PROCEDURE PUT (VAR F);
  10176.  
  10177.        A primitive file system intrinsic procedure.  Writes the value of the
  10178.        file buffer variable F^ at the current file position and then
  10179.        advances the position to the next component.
  10180.  
  10181.        1.  For SEQUENTIAL and TERMINAL mode files, PUT is permitted if
  10182.            the previous operation on F was a REWRITE, PUT, or other
  10183.            WRITE procedure, and if it was not a RESET, GET, or other
  10184.            READ procedure.
  10185.  
  10186.        2.  For DIRECT mode files, PUT may occur immediately after a
  10187.            RESET or GET.
  10188.  
  10189.        Exceptions to these rules cause errors to be generated.  The
  10190.        value of F^ always becomes undefined after a PUT.
  10191.  
  10192.        In MS-Pascal, the value of F^ after a PUT (F) may vary,
  10193.        depending on the target operating system and type of file.  EOF (F)
  10194.        must be TRUE before PUT (F), unless F is a DIRECT mode file.  EOF (F)
  10195.        is always TRUE after PUT (F).  If F^ is a record with variants, the
  10196.        variant with the maximum size is written.
  10197.  
  10198.  
  10199.  16.1.2  RESET and REWRITE
  10200.  
  10201.  
  10202.  The procedures RESET and REWRITE are used to set the current position of a
  10203.  file to its beginning. RESET is used to prepare for later GET and READ
  10204.  operations. REWRITE is used to prepare for later PUT and WRITE operations.
  10205.  
  10206.  
  10207.  PROCEDURE RESET (VAR F);
  10208.  
  10209.        A primitive file system intrinsic procedure.  Resets the current file
  10210.        position to its beginning and does a GET (F).  If the file is not
  10211.        empty, the first component of F is assigned to the buffer variable
  10212.        F^, and EOF (F) becomes false.  If the file is empty, the value of F^
  10213.        is undefined and EOF (F) becomes  true.  RESET initializes a file F
  10214.        prior to its being read.  For DIRECT files, writing can be done after
  10215.        RESET as well.
  10216.  
  10217.        In MS-Pascal, a RESET closes the file and then opens it in a way
  10218.        that is dependent on the operating system.  An error occurs if the
  10219.        filename has not been set (as a program parameter or with ASSIGN or
  10220.        READFN) or if the file cannot be found by the operating system.  If
  10221.        an error occurs during RESET, the file is closed, even if the file
  10222.        was opened correctly and the error came with the initial GET.
  10223.  
  10224.        RESET (INPUT) is done automatically when a program is
  10225.        initialized, but is also allowed explicitly.  RESET on a file with
  10226.        mode DIRECT allows either reading or writing, but the file is not
  10227.        created automatically.  Also, the initial GET reads record number one
  10228.        on a DIRECT mode file.
  10229.  
  10230.        Note that an explicit GET (F) immediately following a RESET (F)
  10231.        assigns the second component of the file to the buffer variable.
  10232.        However, a READ (F, X) following a RESET (F) sets X to the first
  10233.        component of F, since READ (F, X) is "X := F^; GET (F)".
  10234.  
  10235.  
  10236.  PROCEDURE REWRITE (VAR F);
  10237.  
  10238.        A primitive file system intrinsic procedure.  Positions the current
  10239.        file to its beginning.  The value of F^ is undefined and EOF (F)
  10240.        becomes TRUE.  This is needed to initialize a file F before writing
  10241.        (for DIRECT files, reading can be done after REWRITE too).
  10242.  
  10243.        In MS-Pascal, a REWRITE closes the file and then opens it in a
  10244.        way that is dependent on the operating system.  If the file does not
  10245.        exist in the operating system, it is created. If it does exist, its
  10246.        old value is lost (unless it has mode DIRECT).  The filename must
  10247.        have been set (as a program parameter or with ASSIGN or READFN).  If
  10248.        an error occurs during REWRITE, the file is closed.  If possible, an
  10249.        existing file with the same name is not affected when a REWRITE error
  10250.        occurs, but with some target operating systems the existing file may
  10251.        be deleted.
  10252.  
  10253.        REWRITE (OUTPUT) is done automatically when a program is
  10254.        initialized, but can also be done explicitly if desired.  REWRITE on
  10255.        a DIRECT mode file allows both reading and writing.  REWRITE does not
  10256.        do an initial PUT the way RESET does an initial GET.
  10257.  
  10258.  
  10259.  16.1.3  EOF and EOLN
  10260.  
  10261.  
  10262.  The functions EOF and EOLN check for end-of-file and end-of-line
  10263.  conditions, respectively. They return a BOOLEAN result. In general, these
  10264.  values indicate when to stop reading a line or a file.
  10265.  
  10266.  
  10267.  FUNCTION EOF : BOOLEAN;
  10268.  FUNCTION EOF (VAR F) : BOOLEAN;
  10269.  
  10270.        A primitive file system intrinsic function.  Indicates whether
  10271.        the buffer variable F^ is positioned at the end of the file F for
  10272.        SEQUENTIAL and TERMINAL file modes. Therefore, if EOF (F) is TRUE,
  10273.        either the file is being written or the last GET has reached the end
  10274.        of the file.
  10275.  
  10276.        With the DIRECT file mode, if EOF (F) is TRUE, either the last
  10277.        operation was a WRITE (the file may or may not be positioned at the
  10278.        end in this case) or the last GET reached the end of the file.
  10279.  
  10280.        EOF without a parameter is equivalent to EOF (INPUT).
  10281.        EOF (INPUT) is generally never TRUE, except in some operating systems
  10282.        where a particular terminal character generates an end-of-file
  10283.        status, or if INPUT is reassigned to another file.  Calling the
  10284.        EOF (F) function accesses the buffer variable F^.
  10285.  
  10286.  
  10287.  FUNCTION EOLN : BOOLEAN;
  10288.  FUNCTION EOLN  (VAR F) : BOOLEAN;
  10289.  
  10290.        A primitive file system intrinsic function.  Indicates whether
  10291.        the current position of the file is at the end of a line in the
  10292.        textfile F after a GET (F).  The file must have ASCII structure.
  10293.  
  10294.        According to the ISO standard, calling EOLN (F) when EOF (F) is
  10295.        TRUE is an error.  In MS-Pascal, this error is caught in most cases.
  10296.        The file F must be a file of type TEXT.
  10297.  
  10298.        If EOLN (F) is TRUE, the value of F^ is a space, but the file is
  10299.        positioned at a line marker.  EOLN without a parameter is equivalent
  10300.        to EOLN (INPUT).  Calling the EOLN (F) function accesses the buffer
  10301.        variable F^.
  10302.  
  10303.  
  10304.  16.1.4  PAGE
  10305.  
  10306.  
  10307.  The procedure PAGE helps in formatting textfiles. It is not a "necessary"
  10308.  procedure in the same sense as GET and PUT.
  10309.  
  10310.  
  10311.  PROCEDURE PAGE;
  10312.  PROCEDURE PAGE (VAR F);
  10313.  
  10314.        A primitive file system intrinsic procedure.  Causes skipping to the
  10315.        top of a new page when the textfile F is printed. Since PAGE writes
  10316.        to the file, the initial conditions described for PUT must be TRUE.
  10317.        The file must have ASCII structure. PAGE without a parameter is
  10318.        equivalent to PAGE (OUTPUT).
  10319.  
  10320.        If F is not positioned at the start of a line, PAGE (F) first
  10321.        writes a line marker to F.  If F has mode SEQUENTIAL or DIRECT, then
  10322.        PAGE (F) writes a form feed, CHR (12).  If F has mode TERMINAL, the
  10323.        effect is defined by the target operating system interface, which
  10324.        will usually also write a form feed.
  10325.  
  10326.  
  10327.  16.1.5  Lazy Evaluation
  10328.  
  10329.  
  10330.  Lazy evaluation is designed to solve a recurring problem in Pascal,
  10331.  specifically, how to READ from a terminal in a natural way.
  10332.  
  10333.  The underlying problem is that the ISO standard defines the procedure
  10334.  RESET with an initial GET.  Although acceptable in Pascal's original batch
  10335.  processing, sequential file environment, this kind of read-ahead doesn't
  10336.  work for interactive I/O.
  10337.  
  10338.  Lazy evaluation in MS-Pascal provides for deferring actual physical
  10339.  input (textfiles only) when a buffer variable is evaluated.
  10340.  
  10341.  For example, if a normal file is RESET and then READ, the RESET
  10342.  procedure calls the GET procedure, which sets the buffer variable to the
  10343.  first component of the file. However, if the file is a terminal, this first
  10344.  component does not yet exist!
  10345.  
  10346.  Therefore, at a terminal, you must first type a character to
  10347.  accommodate the GET procedure. Only then would you be prompted for any
  10348.  input.
  10349.  
  10350.  Lazy evaluation eliminates this problem for textfiles by giving
  10351.  the file's buffer variable a special status value that is either "full" or
  10352.  "empty."
  10353.  
  10354.  The normal condition after a GET (F) is empty. The status is full
  10355.  after a buffer variable has been assigned to or assigned from.  Full
  10356.  implies that the buffer variable value is equal to the currently pointed-to
  10357.  component.  Empty implies just the opposite, that the buffer variable value
  10358.  does not equal the value of the currently pointed-to component and input to
  10359.  the buffer variable has been deferred. Table 16.2 summarizes these rules.
  10360.  
  10361.  
  10362.  Table 16.2
  10363.  Lazy Evaluation
  10364. ╓┌──────────┌────────┌───────────────────────────┌───────────────────────────╖
  10365.             Status                               Status
  10366.  Statement  at call  Action                      on exit
  10367.  ───────────────────────────────────────────────────────────────────────────
  10368.  GET (F)    Full     Point to next file com-     Empty
  10369.                      ponent. Becomes EMPTY
  10370.                      since value pointed to is
  10371.                      not in buffer variable.
  10372.  
  10373.  GET (F)    Empty    Load buffer variable with   Empty
  10374.                      current file component,
  10375.                      then point to next file
  10376.             Status                               Status
  10377.  Statement  at call  Action                      on exit
  10378.                     then point to next file
  10379.                      component. Becomes EMPTY
  10380.                      since value pointed to is
  10381.                      not in buffer variable.
  10382.  
  10383.  Reference  Full     No action required.         Full
  10384.    to F^
  10385.  
  10386.  Reference  Empty    Load buffer variable with   Full
  10387.    to F^             current file component.
  10388.  
  10389.  Note that RESET (F) first sets the status full and then calls GET, which
  10390.  sets the status to empty without any physical input.
  10391.  
  10392.  Example of lazy evaluation with automatic REWRITE call:
  10393.  
  10394.       {INPUT is automatically a textfile.}
  10395.       {RESET (INPUT); done automatically.}
  10396.       WRITE (OUTPUT, "Enter number: ");
  10397.       READLN (INPUT, FOO);
  10398.  
  10399.  The automatic initial call to the RESET procedure calls a GET
  10400.  procedure, which changes the buffer variable status from full to empty. The
  10401.  first physical action to the terminal is the prompt output from the WRITE.
  10402.  READLN does a series of the following operations:
  10403.  
  10404.      temp := INPUT^;
  10405.      GET (INPUT)
  10406.  
  10407.  Physical input occurs when each INPUT^ is fetched and the GET
  10408.  procedure sets the status back to empty.
  10409.  
  10410.  READLN ends with the sequence:
  10411.  
  10412.      WHILE NOT EOLN DO GET (INPUT);
  10413.      GET (INPUT)
  10414.  
  10415.  This operation skips trailing characters and the line marker. The
  10416.  EOLN function invokes the physical input. Entering the carriage return sets
  10417.  the EOLN status. Both the GET procedure in the WHILE loop and the trailing
  10418.  GET set the status back to empty. The last physical input in the sequence
  10419.  above is reading the carriage return.
  10420.  
  10421.  
  10422.  16.1.6  Concurrent I/O
  10423.  
  10424.  
  10425.  On operating systems that support it, concurrent I/O permits a GET or
  10426.  PUT procedure to initiate the I/O and immediately return to the calling
  10427.  program. It is only used for BINARY structure files.
  10428.  
  10429.  The program can do computation while the buffer variable is being
  10430.  filled or emptied. The buffer variable has another special status value
  10431.  that can be "ready" or "busy."  If the status is busy when the buffer
  10432.  variable needs to be accessed, the program must wait until the status
  10433.  becomes ready.
  10434.  
  10435.  For example, the following program fragment reads the file IN_FILE,
  10436.  does some computation with the current value, and then writes it to the
  10437.  file OUT_FILE:
  10438.  
  10439.       WHILE NOT EOF (IN_FILE) DO
  10440.         {Check for end of input and}
  10441.         {wait until IN_FILE is ready.}
  10442.  
  10443.       BEGIN
  10444.         READ (IN_FILE, BUFF);
  10445.         {IN_FILE is ready, so assign it to BUFF;}
  10446.         {start reading next component.}
  10447.  
  10448.         OPERATE (BUFF);
  10449.         {Go process value during READ and WRITE.}
  10450.  
  10451.         WRITE (OUT_FILE, BUFF)
  10452.         {Wait until OUT_FILE is ready,}
  10453.         {then assign BUFF and start writing.}
  10454.  
  10455.       END
  10456.  
  10457.  The preceding example uses READ and WRITE procedures. Note that the
  10458.  following two lines are equivalent:
  10459.  
  10460.       READ (IN_FILE, BUFF)
  10461.       BUFF := IN_FILE^;  GET (IN_FILE)
  10462.  
  10463.  So are these two:
  10464.  
  10465.       WRITE (OUT_FILE, BUFF)
  10466.       OUT_FILE^ := BUFF; PUT (OUT_FILE)
  10467.  
  10468.  Concurrent I/O applies to the procedures GET and PUT, as well as to
  10469.  the procedures READ and WRITE.  In practice, it is unusual for the
  10470.  Microsoft Pascal runtime system to handle concurrency. See Appendix B,
  10471.  "Version Specifics," in the Microsoft Pascal Compiler User's Guide for
  10472.  information regarding your implementation.
  10473.  
  10474.  When accessing the buffer variable, either for lazy evaluation or
  10475.  concurrency, MS-Pascal generates an I/O system call. However, if the buffer
  10476.  variable is an actual reference parameter, the procedure or function using
  10477.  that parameter can do I/O to the same file, and these special calls cannot
  10478.  be executed.
  10479.  
  10480.  Passing any buffer variable as a reference parameter is an error in
  10481.  MS-Pascal, although only a warning is given. Calling GET or PUT has an
  10482.  undefined effect on a file buffer variable accessed indirectly through a
  10483.  reference parameter. Assigning the address of a buffer variable to an
  10484.  address type variable is equally dangerous, since this bypasses the lazy
  10485.  evaluation and concurrency mechanisms.
  10486.  
  10487.  
  10488.  16.2  Textfile Input and Output
  10489.  
  10490.  
  10491.  Human-readable input and output in standard Pascal are done with
  10492.  textfiles. Textfiles are files of type TEXT and always have ASCII
  10493.  structure. Normally, the standard textfiles INPUT and OUTPUT are given as
  10494.  program parameters in the PROGRAM heading:
  10495.  
  10496.       PROGRAM IN_AND_OUT (INPUT, OUTPUT);
  10497.  
  10498.  Other textfiles usually represent some input or output device such as
  10499.  a terminal, a card reader, a line printer, or an operating system disk
  10500.  file.  The extend level permits using additional files not given as program
  10501.  parameters.
  10502.  
  10503.  In order to facilitate the handling of textfiles, the four standard
  10504.  procedures READ, READLN, WRITE, and WRITELN are provided in addition to the
  10505.  procedures GET and PUT.
  10506.  
  10507.      1.  READ and READLN
  10508.  
  10509.          The procedures READ and READLN read data from textfiles. READ
  10510.          and READLN are defined in terms of the more primitive operation,
  10511.          GET.  The procedure READLN is very much like READ, except that it
  10512.          reads up to and including the end-of-line.
  10513.  
  10514.      2.  WRITE and WRITELN
  10515.  
  10516.          The procedures WRITE and WRITELN write data to textfiles.
  10517.          WRITE and WRITELN are defined in terms of the more primitive
  10518.          operation, PUT.  The procedure WRITELN writes a line marker to the
  10519.          end of a line. In all other respects, WRITELN is analogous to
  10520.          WRITE.
  10521.  
  10522.  These procedures are more flexible in the syntax for their parameter
  10523.  lists, allowing, among other things, for a variable number of parameters.
  10524.  Moreover, the parameters need not necessarily be of type CHAR, but can also
  10525.  be of certain other types, in which case the data transfer is accompanied
  10526.  by an implicit data conversion operation.  In some cases, parameters can
  10527.  include additional formatting values that affect the data conversions used.
  10528.  
  10529.  If the first variable is a file variable, then it is the file to be
  10530.  read or written. Otherwise, the standard files INPUT and OUTPUT are
  10531.  automatically assumed as default values in the cases of reading and
  10532.  writing, respectively.
  10533.  
  10534.  These two files have TERMINAL mode and ASCII structure and are
  10535.  predeclared as:
  10536.  
  10537.      VAR INPUT, OUTPUT: TEXT;
  10538.  
  10539.  In MS-Pascal, the files INPUT and OUTPUT are treated like other
  10540.  textfiles. They can be used with ASSIGN, CLOSE, RESET, REWRITE, and the
  10541.  other procedures and functions. However, even if present as program
  10542.  parameters, they are not initialized with a filename.  Instead, they are
  10543.  assigned to the user's terminal.  RESET of INPUT and REWRITE of OUTPUT are
  10544.  done automatically, whether or not they are present as program parameters.
  10545.  
  10546.  Textfiles represent a special case among file types insofar as they
  10547.  are structured into lines by "line markers."  If, upon reading a textfile
  10548.  F, the file position is advanced to a line marker (i.e., past the last
  10549.  character of a line), then the value of the buffer variable F^ becomes a
  10550.  blank, and the standard function EOLN (F) yields the value true.  For
  10551.  example:
  10552.  
  10553.       +---+---+---+---+---+---+---+---+---+---+---+
  10554.       |'L'|'I'|'N'|'E'|'O'|'F'|'T'|'E'|'X'|'T'|   |
  10555.       +---+---+---+---+---+---+---+---+---+---+---+
  10556.                                                 
  10557.                                                 │
  10558.                 {EOLN = TRUE} {F^ = ' '}
  10559.  
  10560.  Advancing the file position once more causes one of three things to
  10561.  happen:
  10562.  
  10563.      1.  If the end of the file is reached, then EOF (F) becomes TRUE.
  10564.  
  10565.      2.  If the next line is empty, a blank is assigned to F^ and EOLN (F)
  10566.          remains TRUE.
  10567.  
  10568.      3.  Otherwise, the first character of the next line is assigned to F^
  10569.          and EOLN (F) is set to FALSE.
  10570.  
  10571.  Since line markers are not elements of type CHAR in standard Pascal,
  10572.  they can, in theory, only be generated by the procedure WRITELN.  However,
  10573.  in MS-Pascal, an actual character may be used for the line marker.  It may,
  10574.  therefore, be possible to WRITE a line marker, but not to READ one.
  10575.  
  10576.  When a textfile being written is closed, a final line marker is
  10577.  automatically appended to the last line of any nonempty file in which the
  10578.  last character is not already a line marker.
  10579.  
  10580.  When a textfile being read reaches the end of a nonempty file, a line
  10581.  marker for the last line is returned even if one was not present in the
  10582.  file. Therefore, lines in a textfile always end with a line marker.
  10583.  
  10584.  Any list of data written by a WRITELN is usually readable with the
  10585.  same list in a READLN (unless an LSTRING occurs that is not on the end of
  10586.  the list).
  10587.  
  10588.  Interactive prompt and response is very easy in MS-Pascal.  To have
  10589.  input on the same line as the response, use WRITE for the prompt. READLN
  10590.  must always be used for the response.  For example:
  10591.  
  10592.  
  10593.       WRITE ('Enter command: ');
  10594.  
  10595.       READLN (response);
  10596.  
  10597.  If no file is given, most of the textfile procedures and functions
  10598.  assume either the INPUT file or the OUTPUT file.  For example, if I is of
  10599.  type INTEGER, then READ (I) is the same as READ (INPUT, I).
  10600.  
  10601.  
  10602.  16.2.1  READ and READLN
  10603.  
  10604.  
  10605.  PROCEDURE READ
  10606.  PROCEDURE READLN
  10607.  
  10608.        File system intrinsic procedures for textfile I/O. READ and READLN
  10609.        read data from textfiles. Both are defined in terms of the more
  10610.        primitive operation, GET. That is, if P is of type CHAR, then
  10611.        READ (F, P) is equivalent to:
  10612.  
  10613.            BEGIN
  10614.               P := F^;
  10615.               {Assign buffer variable F^ to P.}
  10616.               GET (F)
  10617.               {Assign next component of file to F^.}
  10618.            END
  10619.  
  10620.        READ can take more than a single parameter, as in
  10621.        READ (F, P1, P2, ... Pn). This is equivalent to the following:
  10622.  
  10623.            BEGIN
  10624.               READ (F, P1);
  10625.               READ (F, P2);
  10626.                 .
  10627.                 .
  10628.               READ (F, Pn)
  10629.            END
  10630.  
  10631.        The procedure READLN is very much like READ, except that it
  10632.        reads up to and including the end-of-line.  At the primitive GET
  10633.        level, without parameters, READLN is equivalent to the following:
  10634.  
  10635.            BEGIN
  10636.              WHILE NOT EOLN (F) DO GET (F);
  10637.              GET (F)
  10638.            END
  10639.  
  10640.        A READLN with parameters, as in READLN (F, P1, P2, ... Pn), is
  10641.        equivalent to the following:
  10642.  
  10643.            BEGIN
  10644.               READ (F, P1, P2, Pn);
  10645.               READLN (F)
  10646.            END
  10647.  
  10648.        READLN is often used to skip to the beginning of the next line.
  10649.        It can only be used with textfiles (ASCII mode).
  10650.  
  10651.        If no other file is specified, both READ and READLN read from
  10652.        the standard INPUT file. Therefore, the name INPUT need not be
  10653.        designated explicitly. For example, these two READ statements perform
  10654.        identical actions:
  10655.  
  10656.            READ (P1, P2, P3)
  10657.            {Reads INPUT by default}
  10658.            READ (INPUT, P1, P2, P3)
  10659.  
  10660.        At the standard level, parameters P1, P2, and P3 above must be
  10661.        of one of the following types:
  10662.  
  10663.            CHAR
  10664.            INTEGER
  10665.            REAL
  10666.  
  10667.        The extend level also allows READ variables of the following
  10668.        types:
  10669.  
  10670.            WORD
  10671.            an enumerated type
  10672.            BOOLEAN
  10673.            INTEGER4
  10674.            a pointer type
  10675.            STRING
  10676.            LSTRING
  10677.  
  10678.        When the compiler reads a variable of a subrange type, the value read
  10679.        must be in range. Otherwise, an error occurs, regardless of the
  10680.        setting of the range checking switch.
  10681.  
  10682.        The procedure READ can also read from a file that is not a
  10683.        textfile (e.g., has BINARY mode). The form READ (F, P1, P2, ... Pn)
  10684.        can be used on a BINARY file.  However, this READ will not work as
  10685.        expected after a SEEK on a DIRECT mode file. For BINARY files,
  10686.        READ (F, X) is equivalent to:
  10687.  
  10688.            BEGIN
  10689.               X := F^;
  10690.               GET (F)
  10691.            END
  10692.  
  10693.  
  10694.  16.2.2  READ Formats
  10695.  
  10696.  
  10697.  The READ process for formatted types (everything except CHAR, STRING,
  10698.  and LSTRING) first reads characters into an internal LSTRING and then
  10699.  decodes the string to get the value.
  10700.  
  10701.  Three important points apply to formatted reads:
  10702.  
  10703.      1.  Leading spaces, tabs, form feeds, and line markers are skipped.
  10704.          For example, when doing READLN (I, J, K) where I, J, and K are
  10705.          integers, the numbers can all be on the same line or spread
  10706.          over several lines.
  10707.  
  10708.      2.  Characters are read as long as they are in the set of
  10709.          characters valid for the type wanted. For example, "-1-2-3" is
  10710.          read as the string of characters for a single INTEGER, but
  10711.          gives an error when the string is decoded. This means that
  10712.          items should be separated by spaces, tabs, line markers, or
  10713.          characters not permitted in the format.
  10714.  
  10715.      3.  M and N values in READ are ignored, except as noted for an N
  10716.          value with enumerated types. M and N parameters are not
  10717.          accepted in BINARY reads.
  10718.  
  10719.  Most of the formatting rules below apply to the function DECODE, as
  10720.  well.
  10721.  
  10722.      1.  INTEGER and WORD types
  10723.  
  10724.          If P is of type INTEGER, WORD, or a subrange thereof, then
  10725.          READ (F, P) implies reading a sequence of characters from F which
  10726.          form a number according to the normal Pascal syntax, and then
  10727.          assigning the number to P. Nondecimal notation (16#C007, 8#74,
  10728.          10#19, 2#101, #Face) is accepted for both INTEGER and WORD, with a
  10729.          radix of 2 through 36. If P is of an INTEGER type, a leading plus
  10730.          (+) or minus (-) sign is accepted. If P is of a WORD type, then
  10731.          numbers up to MAXWORD are accepted (32768..65535).
  10732.  
  10733.      2.  REAL and INTEGER4 types
  10734.  
  10735.          If P is of type REAL, or at the extend level type INTEGER4, READ
  10736.          (F, P) implies reading a sequence of characters from F that form a
  10737.          number of the appropriate type and assigning the number to P.
  10738.          Nondecimal notation is not accepted for REAL numbers, but is
  10739.          accepted for INTEGER4 numbers. When reading a REAL value, a number
  10740.          with a leading or trailing decimal point is accepted, even though
  10741.          this form gives a warning if used as a constant in a program.
  10742.  
  10743.      3.  Enumerated and Boolean types
  10744.  
  10745.          At the extend level, if P is an enumerated type or BOOLEAN, a
  10746.          number is read as a WORD subrange and a value assigned to P such
  10747.          that the number is the ORD of the enumerated type's value. In
  10748.          addition, if P is of type BOOLEAN, reading one of the character
  10749.          sequences 'TRUE' or 'FALSE' cause true and false, respectively, to
  10750.          be assigned to P.  The number read must be in the range of the ORD
  10751.          values of the variable.
  10752.  
  10753.          Also at the extend level, if the parameter P is an enumerated
  10754.          type and includes the :N notation as in READ (P::N),
  10755.          characters are read from the file F that form a valid identifier or
  10756.          number. If the characters form a number it is assumed to be the
  10757.          ORD value described in the previous paragraph, and if the
  10758.          characters form an identifier that is one of the enumerated type's
  10759.          constant identifiers, its value is assigned to P. In addition, if
  10760.          the variable is BOOLEAN, reading one of the digits 1 or 0 causes
  10761.          either true or false to be assigned to the BOOLEAN variable.
  10762.          'TRUE' and 'FALSE' are  also accepted as the BOOLEAN constant
  10763.          identifiers.
  10764.  
  10765.          The actual value of N is ignored: using the N notation
  10766.          directs the compiler to save the enumerated type's constant
  10767.          identifiers and make them available to the applicable READ routine.
  10768.          Omitting the N notation saves memory that would be used for the
  10769.          identifiers.
  10770.  
  10771.      4.  Reference types
  10772.  
  10773.          At the extend level, if P is a pointer type, a number is read as a
  10774.          WORD and assigned to P, in a way that depends on your
  10775.          implementation, so that writing a pointer and later reading it
  10776.          yields the same pointer value.  The address types should be read as
  10777.          WORDs using (.R) or (.S) notation.
  10778.  
  10779.      5.  String types
  10780.  
  10781.          At the extend level, if P is a STRING (n), then the next "n"
  10782.          characters are read sequentially into P. Preceding line markers,
  10783.          spaces, tabs, or form feeds are not skipped. If the line marker is
  10784.          encountered before n characters have been read, the remaining
  10785.          characters in P are set to blanks and the file position remains at
  10786.          the line marker.
  10787.  
  10788.          If the STRING is filled with n characters before the line
  10789.          marker is encountered, the file position remains at the next
  10790.          character. In a few implementations there may be a limit of 255
  10791.          characters on the length of a STRING read. P can be the super
  10792.          array type STRING (e.g., a reference parameter or pointer referent
  10793.          variable).
  10794.  
  10795.          At the extend level, if P is an LSTRING (n), then the next
  10796.          "n" characters are read sequentially into P, and the length of the
  10797.          LSTRING is set to "n".  Preceding line markers, spaces, tabs, or
  10798.          form feeds are not skipped. If the line marker is encountered
  10799.          before "n" characters have been read, the length of the LSTRING is
  10800.          set to the number of characters read and the file position remains
  10801.          at the line marker.
  10802.  
  10803.          If the LSTRING is filled with "n" characters before the line
  10804.          marker is encountered, the file position remains at the next
  10805.          character. P can be the super array type LSTRING (e.g., a
  10806.          reference parameter or pointer referent variable). READ (LSTRING)
  10807.          is handy when reading entire lines from a textfile, especially when
  10808.          the length of the line is needed. For example, the easiest way to
  10809.          copy a textfile is by using READLN and WRITELN with an LSTRING
  10810.          variable.
  10811.  
  10812.          Currently, READ and READLN do not use M field width
  10813.          parameters: you cannot read the line '123456' as two INTEGER
  10814.          numbers with READ (I:3, J:3). However, you can read two
  10815.          LSTRING (3) items and then decode them to achieve the same effect.
  10816.  
  10817.  
  10818.  16.2.3  WRITE and WRITELN
  10819.  
  10820.  
  10821.  PROCEDURE WRITE
  10822.  PROCEDURE WRITELN
  10823.  
  10824.        File system intrinsic procedures for textfile I/O. WRITE and
  10825.        WRITELN write textfiles. Both are defined in terms of the more
  10826.        primitive operation, PUT; that is, if P is an expression of type CHAR
  10827.        and F is a file of type TEXT, then WRITE (F, P) is equivalent to:
  10828.  
  10829.            BEGIN
  10830.              F^ := P;
  10831.              {Assign P to buffer variable F^.}
  10832.              PUT (F)
  10833.              {Assign F^ to next component of file.}
  10834.            END
  10835.  
  10836.        WRITE can take more than one parameter, as in
  10837.        WRITE (F, P1, P2,... Pn).  This is equivalent to the following:
  10838.  
  10839.            BEGIN
  10840.               WRITE (F, P1);
  10841.               WRITE (F, P2);
  10842.                 .
  10843.                 .
  10844.               WRITE (F, Pn)
  10845.            END
  10846.  
  10847.        The procedure WRITELN writes a line marker to the end of a
  10848.        line.  In all other respects, WRITELN is analogous to WRITE.  Thus,
  10849.        WRITELN (F, P1, P2, ... Pn) is equivalent to:
  10850.  
  10851.            BEGIN
  10852.               WRITE (F, P1, P2, ... Pn);
  10853.               WRITELN (F)
  10854.            END
  10855.  
  10856.        If either WRITE or WRITELN has no file parameter, the default
  10857.        file parameter is OUTPUT.  Therefore, the first statement in each of
  10858.        the following pairs is equivalent to the second:
  10859.  
  10860.            WRITE (P1, P2, ... Pn)
  10861.            WRITE (OUTPUT, P1, P2, ... Pn)
  10862.  
  10863.            WRITELN (P1, P2, ... Pn)
  10864.            WRITELN (OUTPUT, P1, P2, ... Pn)
  10865.  
  10866.        At the standard level, parameters in a WRITE can be expressions
  10867.        of any of the following types:
  10868.  
  10869.            CHAR
  10870.  
  10871.            INTEGER
  10872.  
  10873.            REAL
  10874.  
  10875.            BOOLEAN
  10876.  
  10877.            STRING
  10878.  
  10879.        At the extend level, expressions can also be of the following types:
  10880.  
  10881.            WORD
  10882.  
  10883.            INTEGER4
  10884.  
  10885.            LSTRING
  10886.  
  10887.            an enumerated type
  10888.  
  10889.            a pointer type
  10890.  
  10891.        Parameters may take optional M and N values (see Section 16.2.4,
  10892.        "WRITE Formats," for information about M and N parameters).
  10893.  
  10894.        Although the procedure WRITE can also write to a BINARY file
  10895.        (i.e., not a textfile), this is not recommended for DIRECT files
  10896.        after a SEEK operation, because the complementary READ form does not
  10897.        work as you might expect.
  10898.  
  10899.        For BINARY files, WRITE (F, X) is equivalent to:
  10900.  
  10901.            BEGIN
  10902.              F^ := X;
  10903.              PUT (F)
  10904.            END
  10905.  
  10906.        The form WRITE (F, P1, P2, ... Pn) is also acceptable. Normally,
  10907.        BINARY writes do not accept M and N values.
  10908.  
  10909.  
  10910.  16.2.4  WRITE Formats
  10911.  
  10912.  
  10913.  In textfiles, data parameters to WRITE and WRITELN may take on
  10914.  of the following forms:
  10915.  
  10916.       P   P:M   P:M:N   P::N
  10917.  
  10918.  
  10919.  The M and N values can be considered value parameters of type INTEGER
  10920.  and are used for formatting in various ways.  The extend level permits M
  10921.  and N values for both READs and WRITEs, and permits giving N without M, as
  10922.  in:
  10923.  
  10924.      P::N
  10925.  
  10926.  Using them in a nonstandard way is an error not caught at the
  10927.  standard level. In some cases only M, or N, or neither, is actually used;
  10928.  unused M and N values are ignored.
  10929.  
  10930.  Omitting M or N is the same as using the value MAXINT. For example,
  10931.  WRITE (12 : MAXINT) uses the default M value (8 in this case). Currently,
  10932.  M and N values are not accepted for BINARY files. In WRITE, the M value is
  10933.  the field width used as the number of characters to write. In
  10934.  ISO-Pascal, M must be greater than zero, and if the expression being
  10935.  written requires less than M characters, then it is padded on the left with
  10936.  spaces.
  10937.  
  10938.  At the extend level, M can also be negative or zero. If it is
  10939.  negative, the absolute value of M is used, but padding of spaces occurs on
  10940.  the right instead of the left. If it is zero, no characters are written.
  10941.  These are ISO standard errors not caught in MS-Pascal.
  10942.  
  10943.  If the representation of the expression cannot fit in ABS (M)
  10944.  character positions, then extra positions are used as needed for numeric
  10945.  types, or the value is truncated on the right for string types. If M is
  10946.  omitted or equal to MAXINT, a default value is used.
  10947.  
  10948.  The N value signifies:
  10949.  
  10950.      1.  the number of decimal places if P is of type REAL
  10951.  
  10952.      2.  the output radix if P is of type INTEGER, WORD, INTEGER4, or
  10953.          pointer
  10954.  
  10955.      3.  the numeric or identifier value if P is of an enumerated type
  10956.  
  10957.  Most of the following formatting rules apply to the function ENCODE as
  10958.  well.
  10959.  
  10960.      1.  INTEGER and WORD types
  10961.  
  10962.          If P is of type INTEGER, WORD, or a subrange thereof, then the
  10963.          decimal representation of P is written on the file. If P is a
  10964.          negative INTEGER, a leading minus sign is always written. WORD
  10965.          values are never negative. For INTEGER and WORD values, the default
  10966.          M value is 8.
  10967.  
  10968.          If ABS (M) is smaller than the representation of the number,
  10969.          additional character positions are used as needed. N is used to
  10970.          write in hexadecimal, decimal, octal, binary, or other base
  10971.          numbering using N equal to a number from 2 to 36; this is an
  10972.          extension to the ISO standard. If N is not 10 (or omitted or
  10973.          MAXINT), then padding on the left is with zeros and not spaces.
  10974.          Omitting N or setting N to MAXINT or 10 implies a decimal radix.
  10975.  
  10976.          WORD decimal numbers from 32768 to 65535 are written normally
  10977.          and not in their negative integer equivalents. All values written
  10978.          should be separated by spaces or some other character not valid in
  10979.          numbers, so that values are read as separate numbers.
  10980.  
  10981.      2.  REAL and INTEGER4 types
  10982.  
  10983.          If P is of type REAL, a decimal representation of the number P,
  10984.          rounded to the specified number of decimal places, is written on
  10985.          the file. If the N is missing or equal to MAXINT, a floating-point
  10986.          representation of P is written to the file, consisting of a
  10987.          coefficient and a scale factor. If N is included, a rounded
  10988.          fixed-point representation of P is written to the file, with N
  10989.          digits after the decimal point. If N is zero, P is written as a
  10990.          rounded integer, with a decimal point. The default value of M for
  10991.          REAL values is 14.
  10992.  
  10993.          Some examples of WRITE operations on REAL values:
  10994.  
  10995.              This Statement          Produces This Output
  10996.              ───────────────────────────────────────────────────────────────
  10997.              WRITE (123.456)         ' 1.2345600E+02'
  10998.              WRITE (123.456:20)      ' 1.2345600000000E+02'
  10999.              WRITE (123.456::3)      '       123.456'
  11000.              WRITE (123.456:2:3)     ' 123.456'
  11001.              WRITE (123.456:-20:3)   '123.456             '
  11002.  
  11003.          At the extend level, if P is of type INTEGER4, the decimal
  11004.          representation of P is written on the file. The N value is used to
  11005.          set the radix, as in type INTEGER. The default M value is 14.
  11006.  
  11007.      3.  Enumerated and Boolean types
  11008.  
  11009.          At the extend level, if P is an enumerated type and N is omitted or
  11010.          equal to MAXINT then ORD (P) is written on the file, as if it were
  11011.          a WORD. If N is given with the value 1, the enumerated type's
  11012.          constant identifier for the value of P is written on the file, as
  11013.          if it were a STRING. Note that using this N notation causes memory
  11014.          to be allocated for the enumerated type's constant identifiers.
  11015.  
  11016.          At the standard level, if P is of type BOOLEAN, then one of
  11017.          the strings 'TRUE' or 'FALSE' is written to the file as a STRING.
  11018.          The ORD value is never written for BOOLEAN types as it is for
  11019.          enumerated types (although you can use WRITE(ORD(P)) instead).
  11020.  
  11021.      4.  Reference types
  11022.  
  11023.          At the extend level, if P is a pointer type, then P is written as a
  11024.          WORD. This is done in an implementation defined way such that
  11025.          writing a pointer and later reading it produces the same pointer
  11026.          value.  The address types should be written as WORD values using
  11027.          (.R) or (.S) notation.
  11028.  
  11029.      5.  String types
  11030.  
  11031.          If P is of type STRING (n), then the value of P is written on the
  11032.          file. The default value of M is the length of the STRING, "n".  If
  11033.          ABS (M) is less than the length of the string, then only the first
  11034.          ABS (M) characters are written. If M is zero, nothing is written.
  11035.          The right portion of the STRING is always truncated, even if M is
  11036.          negative.  In a few implementations, there may be a limit of 255
  11037.          characters on the length of a STRING write.
  11038.  
  11039.          At the extend level, if P is of type LSTRING (n), then the
  11040.          value of P is written on the file. The default value of M is the
  11041.          current length of the string, P.LEN. If ABS (M) is less than
  11042.          the current length, then only the first ABS (M) characters are
  11043.          written. If M is zero, then nothing is written. The right portion
  11044.          of the LSTRING is always truncated, even if M is negative. If
  11045.          ABS (M) is greater than the current length, spaces, not characters,
  11046.          fill the remaining positions past the length in the LSTRING. Note
  11047.          that a string of M blanks can be written with NULL : M.
  11048.  
  11049.  
  11050.  16.3  Extend Level I/O
  11051.  
  11052.  
  11053.  At the extend level, MS-Pascal has these additional I/O features:
  11054.  
  11055.      1.  You can access three FCB fields: F.MODE, F.TRAP, and F.ERRS.
  11056.  
  11057.      2.  A number of additional procedures are predeclared.
  11058.  
  11059.      3.  Temporary files are available.
  11060.  
  11061.  Section 8.6, "File I/O: Extend Level," discusses FCB fields in the
  11062.  context of files.  The additional procedures and temporary files are
  11063.  described in the following sections.
  11064.  
  11065.  
  11066.  16.3.1  Extend Level Procedures
  11067.  
  11068.  
  11069.  PROCEDURE ASSIGN (VAR F; CONSTS N : STRING);
  11070.  
  11071.        A file system procedure for extend level I/O. Assigns an operating
  11072.        system filename in a STRING (or LSTRING) to a file F. The filename
  11073.        format depends on the target operating system. As a rule, ASSIGN
  11074.        truncates any trailing blanks.  ASSIGN overrides any filename set
  11075.        previously. A filename must be set before the first RESET or REWRITE
  11076.        on a file. ASSIGN on an open file (after RESET or REWRITE but before
  11077.        CLOSE) produces an error. ASSIGN to INPUT or OUTPUT is allowed, but
  11078.        since these two files are opened automatically, they must be closed
  11079.        before being assigned to.
  11080.  
  11081.  
  11082.  PROCEDURE CLOSE (VAR F);
  11083.  
  11084.        A file system procedure for extend level I/O. Performs an operating
  11085.        system close on a file, ensuring that the file access is terminated
  11086.        correctly. This is especially important for file variables allocated
  11087.        on the stack or the heap. Since these files must be closed before a
  11088.        RETURN or DISPOSE loses the file control block, they are closed
  11089.        automatically when a RETURN or DISPOSE releases stack or
  11090.        heap file variables.
  11091.  
  11092.        File variables with the STATIC attribute in procedures and
  11093.        functions are also closed automatically when the procedure or
  11094.        function returns. Files allocated statically at the program, module,
  11095.        or implementation level are automatically closed when the entire
  11096.        program terminates.
  11097.  
  11098.        If necessary, when a CLOSE is executed, a file being written to
  11099.        has its operating system buffers flushed. However, the MS-Pascal
  11100.        buffer variable is not PUT. If a file of type TEXT is being written
  11101.        and the last nonempty line does not end with a line marker, one is
  11102.        added to the end of the last line. If the file has the mode
  11103.        SEQUENTIAL and is being written, an end-of-file is written.
  11104.  
  11105.        Note that some runtime errors may remove control from the MS-
  11106.        Pascal runtime system. In these cases, files being written may not
  11107.        be closed, and the information in them may be lost. A CLOSE on a
  11108.        file that is already closed or never opened (no RESET or REWRITE) is
  11109.        permitted. CLOSE is not ignored if error trapping is on and there
  11110.        was a previous error. CLOSE turns off error trapping for the file,
  11111.        and clears the error status if no errors were found.
  11112.  
  11113.  
  11114.  PROCEDURE DISCARD (VAR F);
  11115.  
  11116.        A file system procedure for extend level I/O. Closes and deletes an
  11117.        open file. DISCARD is much like CLOSE except that the file is
  11118.        deleted.
  11119.  
  11120.  
  11121.  PROCEDURE READFN (VAR F ; P1, P2, ... CR);
  11122.  
  11123.        A file system procedure for extend level I/O.  READFN is the
  11124.        same as READ (not READLN) with two exceptions:
  11125.  
  11126.        1.  File parameter F should be present (INPUT is assumed, but a
  11127.            warning is given if F is omitted).
  11128.  
  11129.        2.  If a parameter P is of type FILE, a sequence of characters
  11130.            forming a valid filename is read from F and assigned to P in
  11131.            the same manner as ASSIGN.
  11132.  
  11133.        Parameters of other types are read in the same way as the READ
  11134.        procedure.
  11135.  
  11136.        Note that READFN is like READ, not like READLN, and does not
  11137.        read the trailing line marker. If the first parameter in a READFN
  11138.        call is a file of any type, it is assumed to be the textfile from
  11139.        which characters are read. It is not assumed that the file's name
  11140.        should be read using INPUT as the default source.
  11141.  
  11142.        READFN is used internally to read a program's parameters. It is
  11143.        useful when reading a filename and assigning the filename to some
  11144.        file in one operation.
  11145.  
  11146.  
  11147.  PROCEDURE READSET
  11148.  (VAR F; VAR L : LSTRING, CONST S : SETOFCHAR);
  11149.  
  11150.        A file system procedure for extend level I/O. READSET reads
  11151.        characters and puts them into L, as long as the characters are in the
  11152.        set S and there is room in L. If no file parameter is given, INPUT
  11153.        is assumed, as in READ and WRITE. Leading spaces, tabs, form feeds,
  11154.        and line markers are always skipped.
  11155.  
  11156.        Reading ceases at the first line marker, which is never in the
  11157.        type CHAR.
  11158.  
  11159.        READSET, along with ENCODE, is used by the runtime system to do
  11160.        the formatted READ procedures, as well as to read filenames with
  11161.        READFN. It is handy when reading and parsing input lines for simple
  11162.        command scanners.
  11163.  
  11164.        In a segmented memory environment, the L and S parameters must
  11165.        reside in the default data segment.
  11166.  
  11167.  
  11168.  PROCEDURE SEEK (VAR F; N : INTEGER4);
  11169.  
  11170.        A file system procedure for extend level I/O. In contrast to normal
  11171.        sequential files, DIRECT files are random access structures. SEEK is
  11172.        used to randomly access components of such files. To use a DIRECT
  11173.        file, the MODE field must be set to DIRECT before the file is opened
  11174.        with RESET or REWRITE; the file, F, must be a DIRECT mode file.
  11175.  
  11176.        If the file is actually read or written sequentially, the usual
  11177.        READ and WRITE procedures can be used.
  11178.  
  11179.        SEEK modifies a field in file F so that the next GET or PUT
  11180.        applies to record number N. The record number parameter N can be of
  11181.        type INTEGER or WORD, as well as of type INTEGER4. For textfiles
  11182.        (ASCII structure), records are lines; for other files (BINARY
  11183.        structure), records are components. Record numbers start at one (not
  11184.        zero). If F is an ASCII file, SEEK sets the lazy evaluation status
  11185.        "empty." If F is a BINARY file, SEEK waits for I/O to finish and sets
  11186.        the concurrent I/O status "ready."
  11187.  
  11188.        SEEK is best illustrated by some examples. Assume for instance,
  11189.        that a BINARY structured, DIRECT mode file contains the following
  11190.        CHAR contents:
  11191.  
  11192.            +---+---+---+---+---+---+---+---+
  11193.            |'A'|'B'|'C'|'D'|'E'|'F'|'G'|   |
  11194.            +---+---+---+---+---+---+---+---+
  11195.         N =  1   2   3   4   5   6   7   8
  11196.  
  11197.        An implicit SEEK 1 is done after a REWRITE or a RESET.  Thus, with
  11198.        DIRECT mode files, the following sequences of commands might be
  11199.        given:
  11200.  
  11201.            RESET (F);
  11202.            {Initial SEEK 1, followed by GET;}
  11203.            {F^ now holds 'A'.}
  11204.            SEEK (F, 5);
  11205.            {File position set to 5; F^ still holds 'A'.}
  11206.            C := F^
  11207.            {C is now equal to 'A'; C does not equal 'E'.}
  11208.  
  11209.        Note that the fifth component is not assigned to C, as you
  11210.        might expect. To obtain this value, the following sequences of
  11211.        commands should be executed:
  11212.  
  11213.            RESET (F);
  11214.            {Initial SEEK 1, followed by GET;}
  11215.            {F^ now holds 'A'.}
  11216.            SEEK (F, 5);
  11217.            {File positioned at 5.}
  11218.            GET (F);
  11219.            {File buffer variable is loaded with 'E'.}
  11220.            C := F^
  11221.            {C gets value 'E'.}
  11222.  
  11223.        The rule to follow is to always follow a SEEK (F, N) with a GET to
  11224.        assure that the nth component is contained in the buffer variable.
  11225.  
  11226.        GET and PUT operate normally on DIRECT mode files with BINARY
  11227.        structured files. However, READ and WRITE work only with ASCII
  11228.        files, i.e., textfiles. READ, in particular, will not work with
  11229.        DIRECT mode BINARY files, because it assigns the buffer variable's
  11230.        value before it performs a GET. On the other hand, GET and PUT are
  11231.        not normally used with ASCII structured DIRECT mode files. Lazy
  11232.        evaluation makes READ and WRITE more appropriate. Care should always
  11233.        be taken when mixing normal sequential operations with DIRECT mode
  11234.        SEEK operations.
  11235.  
  11236.  
  11237.  16.3.2  Temporary Files
  11238.  
  11239.  
  11240.  Sometimes a program needs a "scratch" file for temporary, intermediate
  11241.  data.  If this is the case, you may create a temporary file that is
  11242.  independent of the operating system. To do so, without having to give the
  11243.  file a name in a specific format, ASSIGN a zero character as the name
  11244.  of the file. For example:
  11245.  
  11246.      ASSIGN (F, CHR (0))
  11247.  
  11248.  
  11249.  The file system creates a unique name for the file when it sees that
  11250.  the zero character has been assigned as a name.
  11251.  
  11252.  In environments where several running jobs are sharing a file
  11253.  directory, the job number is usually part of the name. Temporary files are
  11254.  deleted when they are closed, either explicitly or when the file gets
  11255.  deallocated. RESET and REWRITE do not delete the file.
  11256.  
  11257.  
  11258.  
  11259.  Chapter 17  Compilable Parts of a Program
  11260.  
  11261.  ───────────────────────────────────────────────────────────────────────────
  11262.  
  11263.  17.1  Programs
  11264.  
  11265.  17.2  Modules
  11266.  
  11267.  17.3  Units
  11268.  
  11269.         17.3.1  The Interface Division
  11270.  
  11271.         17.3.2  The Implementation Division
  11272.  
  11273.  
  11274.  
  11275.  The Microsoft Pascal Compiler can compile three kinds of source files:
  11276.  programs, modules, and implementations of units. Modules and
  11277.  implementations of units can be compiled separately and later be linked to
  11278.  a program without recompilation. At the standard level, you may compile
  11279.  only entire programs; modules and units are MS-Pascal features available at
  11280.  the extend level.
  11281.  
  11282.  Example of a compilable program:
  11283.  
  11284.       PROGRAM MAIN (INPUT, OUTPUT);
  11285.       BEGIN
  11286.         WRITELN ('Main Program')
  11287.       END. {Main}
  11288.  
  11289.  Example of a compilable module:
  11290.  
  11291.       MODULE MOD_DEMO;
  11292.       {No parameter list in heading}
  11293.         PROCEDURE MOD_PROC;
  11294.         BEGIN
  11295.           WRITELN
  11296.             ('Output from MOD_PROC in MOD_DEMO.')
  11297.         END
  11298.       END. {Mod_Demo}
  11299.  
  11300.  Example of a compilable unit:
  11301.  
  11302.       INTERFACE;
  11303.         UNIT UNIT_DEMO (UNIT_PROC);
  11304.         {UNIT_PROC is the only exported identifier.}
  11305.         PROCEDURE UNIT_PROC
  11306.       END
  11307.       IMPLEMENTATION OF UNIT_DEMO;
  11308.         PROCEDURE UNIT_PROC
  11309.         BEGIN
  11310.           WRITELN
  11311.             ('Output from UNIT_PROC in UNIT_DEMO.')
  11312.         END
  11313.       END. {Unit_Demo}
  11314.  
  11315.  If you compile MODULE MOD_DEMO and UNIT UNIT_DEMO separately, you can
  11316.  later incorporate them into the main program as shown below:
  11317.  
  11318.       {INTERFACE required at the start of any}
  11319.       {source that implements or uses a unit.}
  11320.  
  11321.       INTERFACE;
  11322.         UNIT UNIT_DEMO (UNIT_PROC);
  11323.         PROCEDURE UNIT_PROC
  11324.       END;
  11325.  
  11326.       PROGRAM MAIN (INPUT, OUTPUT);
  11327.       {USES clause below needed to connect}
  11328.       {implementation and program.}
  11329.       USES UNIT_DEMO;
  11330.  
  11331.       {EXTERN declaration needed to connect}
  11332.       {module's procedure.}
  11333.       PROCEDURE MOD_PROC; EXTERN;
  11334.       BEGIN
  11335.         WRITELN ('Output from Main Program.');
  11336.         MOD_PROC;
  11337.         UNIT_PROC
  11338.       END. {End of main program.}
  11339.  
  11340.  When the program MAIN is compiled, the output consists of the following
  11341.  pieces:
  11342.  
  11343.      1.  output from Program MAIN
  11344.  
  11345.      2.  output from MOD_PROC declared in MOD_DEMO
  11346.  
  11347.      3.  output from UNIT_PROC declared in UNIT_DEMO
  11348.  
  11349.  The rules governing the construction and use of programs, modules, and
  11350.  units are discussed in the following sections:
  11351.  
  11352.      Section 17.1, "Programs"
  11353.      Section 17.2, "Modules"
  11354.      Section 17.3, "Units"
  11355.  
  11356.  
  11357.  17.1  Programs
  11358.  
  11359.  
  11360.  Except for its heading and the addition of a period at the end, a
  11361.  Pascal program has the same format as a procedure declaration. The
  11362.  statements between the keywords BEGIN and END are called the body of the
  11363.  program.
  11364.  
  11365.  Example of a program:
  11366.  
  11367.       {Program heading}
  11368.       PROGRAM ALPHA (INPUT, OUTPUT, A_FILE, PARAMETER);
  11369.  
  11370.       {Declaration section}
  11371.       VAR A_FILE : TEXT;  PARAMETER : STRING (10);
  11372.  
  11373.       {Program body}
  11374.       BEGIN
  11375.         REWRITE (A_FILE);
  11376.         WRITELN (A_FILE, PARAMETER)
  11377.       END.
  11378.       {Ends with period (.)}
  11379.  
  11380.  The word "ALPHA" following the reserved word "PROGRAM" is the program
  11381.  identifier. The program identifier becomes the identifier for a
  11382.  parameterless PUBLIC procedure, at a scope above all other identifiers in
  11383.  the program. This procedure also has the PUBLIC identifier ENTGQQ,
  11384.  which is called during initialization to start program execution.
  11385.  
  11386.  You could call the program body as a PUBLIC procedure from another
  11387.  program, or from a module or unit, using the program identifier or ENTGQQ
  11388.  as the procedure name (but doing so is not recommended). This means that
  11389.  you can redeclare the program identifier within a program, and the usual
  11390.  scoping rules apply. The program identifier is at the same level as the
  11391.  predeclared identifiers, so giving a program an identifier like INTEGER or
  11392.  READ generates an error message.
  11393.  
  11394.  The program parameters denote variables that are set from outside the
  11395.  program. The program communicates with its environment through these
  11396.  variables.
  11397.  
  11398.  At the standard level, all variables of any FILE type should be
  11399.  present as program parameters, since there is no other way to give an
  11400.  operating system filename to the file. However, at the extend level,
  11401.  you may use the ASSIGN and READFN procedures to assign filenames, so
  11402.  file variables need not appear as program parameters.
  11403.  
  11404.  Program parameters differ entirely from procedure parameters; they
  11405.  are not passed as parameters to the procedure that is the body of the
  11406.  program. All program parameters must be declared in the variable
  11407.  declaration part of the block constituting the program. If there are no
  11408.  program parameters and the files INPUT and OUTPUT are not referenced, use
  11409.  the following form instead:
  11410.  
  11411.       PROGRAM identifier
  11412.  
  11413.  The two standard files INPUT and OUTPUT receive special treatment as
  11414.  program parameters. Their values are not set like other program
  11415.  parameters and should not be declared, since they are already predeclared.
  11416.  Each should be present as a program parameter if used either explicitly or
  11417.  implicitly in the program:
  11418.  
  11419.       WRITE (OUTPUT, 'Prompt:');   {Explicit use}
  11420.       READLN (INPUT, P);
  11421.  
  11422.       WRITE ('Prompt:')            {Implicit use}
  11423.       READLN (P);
  11424.  
  11425.  The compiler gives a warning if you use them in the program but omit
  11426.  them as program parameters. The only effect of INPUT and OUTPUT as program
  11427.  parameters is to suppress this warning.
  11428.  
  11429.  You may redefine the identifiers INPUT and OUTPUT. However, all
  11430.  textfile input and output procedures and functions (READ, EOLN, etc.) still
  11431.  use the original definition. RESET (INPUT) and REWRITE (OUTPUT) are
  11432.  generated automatically, whether or not they are present as program
  11433.  parameters; you may also generate them explicitly.
  11434.  
  11435.  Program initialization gives a value to every program parameter
  11436.  variable, except INPUT and OUTPUT. Each parameter must be either of a
  11437.  simple type or of a STRING, LSTRING, or FILE type (i.e., any type accepted
  11438.  by the READFN procedure). Program parameters must be entire variables: No
  11439.  component selection is permitted.
  11440.  
  11441.  Internally, each program parameter uses the file INPUT and generates
  11442.  READFN calls. Before each parameter is read, a special call is made to the
  11443.  internal routine PPMFQQ. PPMFQQ gets characters returned from an operating
  11444.  system interface routine called PPMUQQ, which gets them from the command
  11445.  line. PPMFQQ then effectively puts those characters at the start of the
  11446.  file INPUT. The identifier of the parameter is passed to both routines
  11447.  (PPMFQQ and PPMUQQ). Some operating systems then use the identifier as a
  11448.  prompt.
  11449.  
  11450.  The use of program parameters in MS-Pascal can best be illustrated by
  11451.  showing how to change a program into a procedure. Suppose you have a
  11452.  program like the following:
  11453.  
  11454.       PROGRAM ALPHA (INPUT, OUTPUT, P1, P2, ... Pn);
  11455.       declarations
  11456.       {Including those for P1, P2, ... Pn}
  11457.       BEGIN
  11458.         body
  11459.       END.
  11460.  
  11461.  PROGRAM ALPHA could then become the following procedure:
  11462.  
  11463.       PROCEDURE ENTGQQ [PUBLIC];
  11464.       declarations
  11465.       {Including those for P1, P2, ... Pn}
  11466.       BEGIN
  11467.         PPMFQQ ('P1'); READFN (INPUT, P1);
  11468.         PPMFQQ ('P2'); READFN (INPUT, P2);
  11469.         .
  11470.         .
  11471.         PPMFQQ ('Pn'); READFN (INPUT, Pn);
  11472.         PPMEQQ
  11473.         {Called after all parameters are read}
  11474.         program statements
  11475.       END;
  11476.  
  11477.  The action of the interface routine PPMFQQ depends on the target
  11478.  operating system. See your Microsoft Pascal Compiler User's Guide for
  11479.  more information on PPMFQQ and ENTGQQ.
  11480.  
  11481.  Some operating systems have elaborate mechanisms to handle this kind
  11482.  of parameter, using menus and default values. If your system falls into
  11483.  this category, the same mechanism generally applies to MS-Pascal program
  11484.  parameters.
  11485.  
  11486.  Other less sophisticated operating systems pass to a program the
  11487.  remainder of the command line that invoked it; in this case, parameter
  11488.  values are read from the command line.
  11489.  
  11490.  If the operating system does not provide a program parameter
  11491.  mechanism, or if an error occurs while using such a mechanism, or if it
  11492.  does not supply enough parameter values, then the PPMFQQ routine reverts to
  11493.  handling parameter values itself. It prompts you for every parameter with
  11494.  the parameter's identifier and reads the value you give it for the
  11495.  parameter. See Appendix B, "Version Specifics," in your Microsoft Pascal
  11496.  Compiler User's Guide for details on how your implementation initializes
  11497.  program parameters.
  11498.  
  11499.  
  11500.  17.2  Modules
  11501.  
  11502.  
  11503.  Modules provide a simple, straightforward method for combining several
  11504.  compilable segments into one program. Units, described in Section 17.3,
  11505.  "Units," provide a more powerful and structured method for achieving the
  11506.  same end.
  11507.  
  11508.  Basically, a module is a program without a body. The identifier in
  11509.  the module heading has the same scope as a program identifier. The heading
  11510.  can also include attributes that apply to all procedures and functions in
  11511.  the module. There are no module parameters; nor is there a module body. A
  11512.  module ends with the reserved word END and a period.
  11513.  
  11514.  Example of a module:
  11515.  
  11516.       MODULE BETA [PUBLIC]; {Optional attributes}
  11517.  
  11518.       PROCEDURE GAMMA;
  11519.          BEGIN WRITELN ('Gamma') END;
  11520.  
  11521.       FUNCTION DELTA : WORD;
  11522.          BEGIN DELTA := 123 END;
  11523.  
  11524.       END. {No body before END}
  11525.  
  11526.  After the module identifier, you may give one or more attributes (in
  11527.  brackets) to apply to all of the procedures and functions nested directly
  11528.  in the module. Depending on which, if any, attributes you specify, the
  11529.  following assumptions or restrictions apply:
  11530.  
  11531.      1.  If there is no attribute list at all, the PUBLIC attribute is
  11532.          assumed. However, if a list is present but empty, PUBLIC is not
  11533.          assumed.
  11534.  
  11535.      2.  The EXTERN directive used with a particular procedure or function
  11536.          overrides the PUBLIC attribute given (or assumed) for the entire
  11537.          module.
  11538.  
  11539.      3.  EXTERN and ORIGIN cannot be given as attributes for an entire
  11540.          module, although you may specify them for individual procedures and
  11541.          functions.
  11542.  
  11543.      4.  If PURE or INTERRUPT are used, the module must contain only
  11544.          functions for PURE and procedures for INTERRUPT.
  11545.  
  11546.      5.  PUBLIC is the default attribute for all procedures and functions.
  11547.          However, in some cases, a PUBLIC procedure call has more overhead
  11548.          than a purely local one. In other cases, the identifier of a local
  11549.          procedure may conflict with a global identifier passed to the
  11550.          linker. To avoid these problems, use PUBLIC with selected
  11551.          individual procedures and functions and empty brackets for the
  11552.          entire module (e.g., MODULE BETA [];).
  11553.  
  11554.  Although a module contains no body, only declarations, you may use it
  11555.  as a parameterless procedure; that is, you may declare the module
  11556.  identifier as a procedure and call it from other programs, modules, or
  11557.  units. This module procedure (unlike a similar procedure for programs or
  11558.  units) is never called automatically, since there is no way for the
  11559.  compiler to know whether a module has been loaded and thus whether to
  11560.  generate a call to it.
  11561.  
  11562.  However, in some cases, the compiler generates module initialization
  11563.  code that should be executed by calling the module as an EXTERN procedure.
  11564.  If such code is necessary, the compiler gives the warning:
  11565.  
  11566.       Initialize Module
  11567.  
  11568.  If you see this message, declare the module as a parameterless EXTERN
  11569.  procedure and call the procedure once before anything in the module is
  11570.  accessed. (You will need to do this if the module declares any FILE
  11571.  variables.)
  11572.  
  11573.  Given a module M that declares its own file variables, a program that
  11574.  uses M should look like this:
  11575.  
  11576.       PROGRAM P (INPUT, OUTPUT)
  11577.         .
  11578.         .
  11579.       PROCEDURE M; EXTERN;
  11580.       BEGIN
  11581.         M; {Runtime call initializes}
  11582.         .  {file variables.}
  11583.         .
  11584.       END.
  11585.  
  11586.  If the module USES any interfaces that require initialization, the
  11587.  compiler generates a warning that you should declare the module EXTERN and
  11588.  call it as described in the previous paragraph.
  11589.  
  11590.  If module M does not contain any of its own file variables or use any
  11591.  initialized units, there is no need to invoke M as a procedure in the body
  11592.  of the program or to declare it as an EXTERN procedure.
  11593.  
  11594.  Variables within modules are not automatically given any attributes.
  11595.  Except for the initialization of FILE variables mentioned above, variables
  11596.  within modules are the same as program variables.
  11597.  
  11598.  
  11599.  17.3  Units
  11600.  
  11601.  
  11602.  MS-Pascal units provide a structured way to access separately
  11603.  compiled modules. A unit has two parts:
  11604.  
  11605.      1.  an interface
  11606.  
  11607.      2.  an implementation
  11608.  
  11609.  The interface appears at the front of an implementation of a unit and
  11610.  at the front of any program, module, interface, or implementation, that
  11611.  uses a unit.
  11612.  
  11613.  A unit contains constants, types, super types, variables, procedures,
  11614.  and functions, all of which are declared in the interface of the unit. Any
  11615.  program, module, implementation, or another interface may use an interface.
  11616.  An implementation contains the bodies of the procedures and functions in a
  11617.  unit, as well as optional initialization for the unit. The general scheme
  11618.  is shown in Figure 17.1.
  11619.  
  11620.  
  11621.       +---------------------------------------------+
  11622.       |           INTERFACE; UNIT X;                |
  11623.       |           identifier-declarations           |
  11624.       |           END;                              |
  11625.       +-------------------+--+----------------------+
  11626.       | heading           |  | IMPLEMENTATION OF X; |
  11627.       | USES X;           |  | identifier-          |
  11628.       | declarations      |  |  implementations     |
  11629.       | optional-body     |  | optional-body        |
  11630.       | END.              |  | END.                 |
  11631.       +-------------------+  +----------------------+
  11632.  
  11633.             Figure 17.1. A Microsoft Pascal Unit
  11634.  
  11635.  
  11636.  When you are using units, their interfaces go before everything else in a
  11637.  source file, either in an IMPLEMENTATION or in the program, module, or
  11638.  other unit that uses it. In the preceding diagram, the INTERFACE is
  11639.  shared; the same INTERFACE exists in both the IMPLEMENTATION source file
  11640.  and in the other source file. Conversely, any other program, module, or
  11641.  unit could USE UNIT X; similarly, there could be another IMPLEMENTATION OF
  11642.  X, in assembly language, for example.
  11643.  
  11644.  By separating the interface from the implementation, you can write
  11645.  and compile a program before or while writing the implementation. Or, you
  11646.  may load a program with one of several implementations (for example, one in
  11647.  MS-Pascal or one in assembly language). A large MS-Pascal program is often
  11648.  better organized as a main program and a number of units (parts of the MS-
  11649.  Pascal runtime system are organized in this way). However, only a program,
  11650.  module, interface, or implementation can USE a unit, not an individual
  11651.  procedure or function.
  11652.  
  11653.  A program, module, implementation, or interface that uses an interface
  11654.  must start with the source file for that interface. Generally, the
  11655.  interface source file is a separate file, and an $include metacommand
  11656.  at the start of the source file brings in the interface source itself at
  11657.  compile time. Because there is then only one master copy of the interface,
  11658.  this is easier and more reliable than physically inserting the interface
  11659.  everywhere it is used (and running the risk of ending up with several
  11660.  different versions).
  11661.  
  11662.  In some applications, you may want several versions of the same
  11663.  interface. For example, there is a separate version of the MS-Pascal file
  11664.  control block interface for every target file system; the $included file is
  11665.  copied from the desired interface version before the program using it is
  11666.  compiled. Naturally, every version must declare the common identifiers;
  11667.  each might also have some constant values for use in $if metacommands for
  11668.  the version-specific portions of the interface.
  11669.  
  11670.  Suppose the INTERFACE for UNIT X in Figure 17.1 is contained in the
  11671.  file X.INT. If that is so, the compiland using the unit and the
  11672.  IMPLEMENTATION of the unit need only to $include the interface file at the
  11673.  start of the source file, as shown in Figure 17.2.
  11674.  
  11675.  
  11676.       +---------------------------------------------+
  11677.       |          {$INCLUDE:'X.INT'}                 |
  11678.       +--------------------+--+---------------------+
  11679.       | compiland-heading  |  | IMPLEMENTATION OF X;|
  11680.       | USES X;            |  | identifier-         |
  11681.       | declarations       |  |  implementations    |
  11682.       | optional-body      |  | optional-body       |
  11683.       | END.               |  | END.                |
  11684.       +--------------------+  +---------------------+
  11685.  
  11686.              Figure 17.2. Unit With File X.INT
  11687.  
  11688.  
  11689.  An MS-Pascal source file of any kind contains zero or more unit interfaces,
  11690.  separated by semicolons, and followed by a program, a module, or an
  11691.  implementation, which is followed by a period. Each of these entities is
  11692.  called a "division." See Section 17.3.1, "The Interface Division," and
  11693.  Section 17.3.2, "The Implementation Division," for details about divisions.
  11694.  
  11695.  A unit consists of the unit identifier, followed by a list of identifiers
  11696.  in parentheses. These identifiers are called the constituents of the
  11697.  unit and are the ones provided by a unit or required by a program,
  11698.  module, or other unit. The unit is preceded by the keyword UNIT for a
  11699.  provided unit or USES for a required one.
  11700.  
  11701.  All unit identifiers in a source file must be unique. The
  11702.  identifiers in parentheses, however, may differ in the providing and
  11703.  requiring divisions. Correspondence between identifiers provided and
  11704.  required is by position in the list (similar to formal and actual
  11705.  parameters in procedures).
  11706.  
  11707.  The identifier list in a USES clause is optional; if not given, the
  11708.  identifiers in the UNIT list are used by default. Giving different
  11709.  identifiers in a USES clause allows you to change the identifiers in case
  11710.  several different interfaces have identifier conflicts. Multiple USES
  11711.  clauses can be combined; thus, the following statements are equivalent:
  11712.  
  11713.       USES A; USES B; USES C;
  11714.       USES A, B, C;
  11715.  
  11716.  Note also that a unit may introduce optional initialization code.
  11717.  Such code is implied by the words BEGIN and END at the end of an
  11718.  interface and is provided in an optional body in an IMPLEMENTATION.
  11719.  
  11720.  Example of a unit that introduces initialization code:
  11721.  
  11722.  The program file, PLOTBOX:
  11723.  
  11724.       {$include:'GRAPHI'}
  11725.       PROGRAM PLOTBOX (INPUT, OUTPUT);
  11726.         USES GRAPHICS (MOVE, PLOT);
  11727.         {MOVE and PLOT are USEd identifiers.}
  11728.         BEGIN
  11729.           MOVE (0, 0);
  11730.           PLOT (10, 0); PLOT (10, 10);
  11731.           PLOT (0, 10); PLOT (0, 0)
  11732.         END.
  11733.  
  11734.  The interface file, GRAPHI:
  11735.  
  11736.       INTERFACE;
  11737.         UNIT GRAPHICS (BJUMP, WJUMP);
  11738.         {Exported identifiers are BJUMP and WJUMP.}
  11739.         {In the above PROGRAM, MOVE and PLOT}
  11740.         {are aliases for these identifiers.}
  11741.         PROCEDURE BJUMP (X, Y : INTEGER);
  11742.         PROCEDURE WJUMP (X, Y : INTEGER);
  11743.         {Procedure headings only above.}
  11744.       BEGIN
  11745.       {BEGIN implies initialization code.}
  11746.       END;
  11747.  
  11748.  The implementation file:
  11749.  
  11750.       {$include:'GRAPHI'}
  11751.       {$include:'BASEPL'}
  11752.       {The following implementation USES}
  11753.       {the UNIT BASEPL. Thus, the interface}
  11754.       {is included above and the unit}
  11755.       {used below.}
  11756.       IMPLEMENTATION OF GRAPHICS;
  11757.       {Implementation is invisible to user.}
  11758.         USES BASEPLOT;
  11759.          {Procedures BJUMP and WJUMP are}
  11760.          {implemented below.}
  11761.          {Note that only the identifiers}
  11762.          {are given in the heading.}
  11763.          {The parameter lists are given}
  11764.          {in the interface.}
  11765.         PROCEDURE BJUMP;
  11766.           BEGIN DRAWLINE (BLACK, X, Y) END;
  11767.         PROCEDURE WJUMP;
  11768.           BEGIN DRAWLINE (WHITE, X, Y) END;
  11769.       BEGIN
  11770.       {Begin initialization.}
  11771.         DRAWLINE (BLACK, 0, 0)
  11772.       END.
  11773.  
  11774.  The interface file, BASEPL:
  11775.  
  11776.       INTERFACE;
  11777.         UNIT BASEPLOT (BLACK, WHITE, DRAWLINE);
  11778.          {Other identifiers besides procedure}
  11779.          {identifiers can be exported.}
  11780.          {Note that BLACK and WHITE are}
  11781.          {exported constant identifiers.}
  11782.         TYPE RAINBOW = (BLACK, WHITE, RED, BLUE, GREEN);
  11783.         PROCEDURE DRAWLINE (C : RAINBOW; H,V : INTEGER);
  11784.       {No BEGIN; therefore, not an initialized unit.}
  11785.       END;
  11786.  
  11787.  A USES clause may occur only directly after a program, module,
  11788.  interface, or implementation heading. When the compiler encounters
  11789.  a USES clause, it enters each constituent identifier (from the UNIT
  11790.  clause or USES clause itself) in the symbol table. Identifiers for
  11791.  variables, procedures, and functions are associated with the
  11792.  corresponding identifiers in the interface, which then become external
  11793.  references for the linker.
  11794.  
  11795.  If the sample program above were compiled, every reference to the
  11796.  procedure PLOT would generate an external reference to WJUMP. However,
  11797.  references to DRAWLINE would use the same identifier for the external
  11798.  reference.
  11799.  
  11800.  Constants and types (including any super array types) in the
  11801.  interface are simply entered in the program's symbol table (along with the
  11802.  new identifier, if any). Thus, a type in an interface is identical to the
  11803.  corresponding type in the USES clause.
  11804.  
  11805.  Record field identifiers are the same in the program, interface, and
  11806.  implementation. Enumerated type constant identifiers must be given
  11807.  explicitly, if needed; they are not automatically implied by the enumerated
  11808.  type identifier. Labels cannot be provided by an interface, since the
  11809.  target label of a GOTO must occur in the same division as the GOTO.
  11810.  
  11811.  
  11812.  17.3.1  The Interface Division
  11813.  
  11814.  
  11815.  The structure of an interface is as follows:
  11816.  
  11817.      1.  An interface section starts with the reserved word INTERFACE, an
  11818.          optional version number in parentheses, and a semicolon.
  11819.  
  11820.      2.  Next comes the keyword UNIT, the unit identifier, the parenthesized
  11821.          list of exported (constituent) identifiers, and another semicolon.
  11822.  
  11823.      3.  Any other units required by this interface come next, in USES
  11824.          clauses.
  11825.  
  11826.      4.  The last section is the actual declarations for all identifiers
  11827.          given in the interface list, using the usual CONST, TYPE, and VAR
  11828.          sections and procedure and function headings, in any order.  No
  11829.          LABEL or VALUE sections are permitted.
  11830.  
  11831.      5.  The interface ends with BEGIN END if it has initialization, or just
  11832.          with END if  it has no initialization.
  11833.  
  11834.  Except for ORIGIN, which cannot currently be used in interfaces, most
  11835.  available attributes can be given to variables, procedures, and functions.
  11836.  Because the PUBLIC or EXTERN attribute or EXTERN directive is given
  11837.  automatically, you must not specify attributes that may conflict (e.g.,
  11838.  PUBLIC and EXTERN).
  11839.  
  11840.  Usually the only identifiers you declare are the constituents, but
  11841.  other identifiers are permitted. If the interface needs a call to
  11842.  initialize the unit, the keyword BEGIN generates the call. The
  11843.  interface ends with the reserved word END and a semicolon.
  11844.  
  11845.  Example of an interface division:
  11846.  
  11847.       INTERFACE (3);
  11848.         UNIT KEYFILE (FINDKEY, INSKEY, DELKEY, KEYREC);
  11849.           USES KEYPRIM (KFCB, KEYREC);
  11850.  
  11851.           PROCEDURE FINDKEY (CONST NAME : LSTRING;
  11852.               VAR KEY : KEYREC;
  11853.               VAR REC : LSTRING);
  11854.           PROCEDURE INSKEY  (CONST REC : LSTRING;
  11855.               VAR KEY : KEYREC);
  11856.           PROCEDURE DELKEY (CONST KEY : KEYREC);
  11857.           PROCEDURE NEWKEY (CONST KEY : KEYREC);
  11858.         BEGIN
  11859.         {Signifies initialized unit.}
  11860.         END;
  11861.  
  11862.  In this example, KEYREC is part of the unit KEYPRIM, but is exported
  11863.  as part of the unit KEYFILE. KFCB is also part of the KEYPRIM unit, but is
  11864.  not exported by the KEYFILE unit. NEWKEY is defined in the interface, but
  11865.  not exported by the KEYFILE unit. This is permitted, but pointless, since
  11866.  NEWKEY is unknown even in the the implementation of the unit.
  11867.  
  11868.  Memory available at compile time limits the number of identifiers the
  11869.  compiler can process. This limit can be a problem if you have many
  11870.  interfaces, especially interfaces that use other interfaces. The symptom
  11871.  is the following error message:
  11872.  
  11873.      Compiler Out Of Memory
  11874.  
  11875.  The message occurs before the final USES clause in the program,
  11876.  module, or implementation you are compiling. The cure is to reduce the
  11877.  number of identifiers in interfaces USEd by other interfaces. For example,
  11878.  make a single interface that contains only types (and type-related
  11879.  constants) shared by your other interfaces, and only USE this interface
  11880.  in the others.
  11881.  
  11882.  If you include any file variables in the interface, the unit must be
  11883.  initialized. The compiler does not give the usual warning,
  11884.  
  11885.       Initialize Variable
  11886.  
  11887.  when you declare a file in an interface. If your interface contains files,
  11888.  be sure to end it with BEGIN END so that it will be initialized.
  11889.  
  11890.  
  11891.  17.3.2  The Implementation Division
  11892.  
  11893.  
  11894.  You may compile an implementation of a unit separately from other
  11895.  programs, modules, or units, but you must compile it along with its
  11896.  interface.
  11897.  
  11898.  The structure of an implementation is as follows:
  11899.  
  11900.      1.  An implementation of an interface starts with the reserved words
  11901.          IMPLEMENTATION OF, followed by the unit identifier and a semicolon.
  11902.  
  11903.      2.  Next comes a USES clause for units it needs only for its own use.
  11904.  
  11905.      3.  Then comes the usual LABEL, CONSTANT, TYPE, VAR, and VALUE sections
  11906.          and all procedures and functions mentioned as constituents (which
  11907.          must be in the outer block) or used internally, in any order.
  11908.  
  11909.  VALUE and LABEL sections may appear in the implementation, but not in
  11910.  the interface.
  11911.  
  11912.  Example of an implementation:
  11913.  
  11914.       IMPLEMENTATION OF KEYFILE;
  11915.         USES KEYPRIM (KEYBLOCK, KEYREC);
  11916.  
  11917.         VAR KEYTEMP : KEYREC;
  11918.  
  11919.         PROCEDURE FINDKEY;
  11920.           BEGIN
  11921.             .
  11922.             {Code for FINDKEY}
  11923.             .
  11924.           END;
  11925.  
  11926.         PROCEDURE INKEY;
  11927.           BEGIN
  11928.             .
  11929.             {Code for INKEY}
  11930.             .
  11931.           END;
  11932.  
  11933.         PROCEDURE DELKEY;
  11934.           BEGIN
  11935.             .
  11936.             {Code for DELKEY}
  11937.             .
  11938.           END;
  11939.  
  11940.       BEGIN
  11941.         .
  11942.         {Any initialization code goes here.}
  11943.         .
  11944.       END.
  11945.  
  11946.  Constants, variables, and types declared in the interface are not
  11947.  redeclared in the implementation. However, you may declare other "private"
  11948.  ones. Procedures and functions that are constituents of the unit do not
  11949.  include their parameter list (it is implied by the interface) or any
  11950.  attributes. (The PUBLIC attribute is implied, unless the EXTERN directive
  11951.  is given explicitly.)
  11952.  
  11953.  All procedures and functions in the interface must be defined in the
  11954.  implementation. However, they can be given the EXTERN directive so that
  11955.  several implementations (or an implementation and assembly code) can
  11956.  implement a single interface. All procedures and functions with the EXTERN
  11957.  directive must appear first; the compiler checks for this and issues an
  11958.  error message if the EXTERN directive is missing or misplaced.
  11959.  
  11960.  You may implement a unit in assembly language, in which case all variables,
  11961.  procedures, and functions should generate public definitions for the
  11962.  loader. You may also implement units in other programming languages,
  11963.  such as MS-FORTRAN, or in a mixture of languages. If the interface is not
  11964.  implemented in MS-Pascal, it must give the proper calling sequence
  11965.  attribute (and of course you must be familiar with calling sequences and
  11966.  internal representation of parameters).
  11967.  
  11968.  Several MS-Pascal runtime units are implemented partially in MS-Pascal
  11969.  and partially in assembly language. As mentioned, any implementation
  11970.  section that does not implement all interface procedures and functions
  11971.  must, at the start of the implementation, declare such procedures and
  11972.  functions to be EXTERN.
  11973.  
  11974.  An implementation, like a program, may have a body. The body is
  11975.  executed when the program that uses the unit is invoked, so any
  11976.  initialization needed by the unit can be done. This includes internal
  11977.  initialization, such as file variable initialization, as well as user
  11978.  initialization code. If the source file contains several units, each
  11979.  implementation body is called in the order its USES clause appears in the
  11980.  source file. However, initialization code for a unit is executed only
  11981.  once, no matter how many clauses refer to it.
  11982.  
  11983.  The body, as in a program, is a list of statements enclosed with the
  11984.  reserved words BEGIN and END. At initialization time, the version number
  11985.  of the interface with which the implementation was compiled is compared
  11986.  against the version number of the interface with which the program was
  11987.  compiled. These must be the same. This checking prevents you from trying
  11988.  to run a program with obsolete implementations. If no version number is
  11989.  given, zero is assumed.
  11990.  
  11991.  The keyword BEGIN before the final END indicates a unit with
  11992.  initialization. If the word BEGIN is omitted, the implementation must
  11993.  not have a body and no initialization takes place. Uninitialized units
  11994.  lack the following:
  11995.  
  11996.      1.  user initialization code
  11997.  
  11998.      2.  a guarantee of only one initialization
  11999.  
  12000.      3.  a version number check
  12001.  
  12002.  The format for an initialized implementation of a unit is similar to a
  12003.  program:
  12004.  
  12005.       IMPLEMENTATION OF unit-identifier
  12006.       declarations
  12007.       BEGIN
  12008.          body   {Initialization code}
  12009.       END.
  12010.  
  12011.  The format for an uninitialized implementation of a unit is similar
  12012.  to a module:
  12013.  
  12014.       IMPLEMENTATION OF unit-identifier
  12015.       declarations
  12016.       {No initialization code}
  12017.       END.
  12018.  
  12019.  If the implementation for an uninitialized unit declares any files or
  12020.  USES any interfaces that require initialization, the compiler warns you to
  12021.  initialize the implementation. Initialization is done automatically if you
  12022.  add the keyword BEGIN to both the interface and the implementation. As
  12023.  with a module, you can declare an uninitialized unit to be a procedure with
  12024.  the EXTERN attribute and then initialize it by calling it from the program.
  12025.  
  12026.  
  12027.  
  12028.  Chapter 18  Microsoft Pascal Metacommands
  12029.  
  12030.  ───────────────────────────────────────────────────────────────────────────
  12031.  
  12032.  18.1  Language Level Setting and Optimization
  12033.  
  12034.  18.2  Debugging and Error Handling
  12035.  
  12036.  18.3  Source file control
  12037.  
  12038.  18.4  Listing File Control
  12039.  
  12040.  18.5  Listing File Format
  12041.  
  12042.  
  12043.  
  12044.  Metacommands make up the compiler control language. Metacommands are
  12045.  compiler directives that allow you to control such things as the following:
  12046.  
  12047.      1.  Microsoft Pascal language level
  12048.  
  12049.      2.  debugging and error handling
  12050.  
  12051.      3.  optimization level
  12052.  
  12053.      4.  use of the source file during compilation
  12054.  
  12055.      5.  listing file format
  12056.  
  12057.  You can specify one or more metacommands at the start of a comment;
  12058.  you should separate multiple metacommands with either spaces or commas.
  12059.  Spaces, tabs, and line markers between the elements of a metacommand
  12060.  are ignored. Thus, the following are equivalent:
  12061.  
  12062.       {$page:12}
  12063.       {$page : 12}
  12064.  
  12065.  To disable metacommands within comments, place any character that is
  12066.  not a tab or space in front of the first dollar sign, as shown:
  12067.  
  12068.       {x$page:12}
  12069.  
  12070.  You may change compiler directives during the course of a program;
  12071.  for example, most of a program might use $list-, with a few sections
  12072.  using $list+ as needed. Some metacommands, such as $linesize, normally
  12073.  apply to an entire compilation.
  12074.  
  12075.  If you are writing Microsoft Pascal programs for use with other
  12076.  compilers, keep in mind the fact that metacommands are always
  12077.  nonstandard and rarely transportable.
  12078.  
  12079.  Metacommands invoke or set the value of a metavariable.
  12080.  Metavariables are classified as typeless, integer, on/off switch, or
  12081.  string.
  12082.  
  12083.      1.  Typeless metavariables are invoked when used, as in $extend.
  12084.  
  12085.      2.  Integer metavariables can be set to a numeric value, as in
  12086.          $page:101.
  12087.  
  12088.      3.  On/off switches can be set to a numeric value so that a value
  12089.          greater than zero turns the switch on and a value equal or less
  12090.          than zero turns it off, as in $mathck:1.
  12091.  
  12092.      4.  String metavariables can be set to a character string value, such
  12093.          as with $title:'com program'.
  12094.  
  12095.  Table 18.1 illustrates the notational conventions observed in the
  12096.  metacommand descriptions that follow.
  12097.  
  12098.  
  12099.        Table 18.1
  12100.        Metacommand Notation
  12101. ╓┌──────────────────┌────────────────────────────────────────────────────────╖
  12102.        Notation     Meaning
  12103.       ──────────────────────────────────────────────────────────────────────
  12104.                     Metacommand is typeless.
  12105.  
  12106.        + or -       Metacommand is an on/off switch.
  12107.                     + sets value to 1 (on).
  12108.                     - sets value to 0 (off).
  12109.                     Default is indicated by + or - in heading.
  12110.  
  12111.        :<n>         Metacommand is an integer.
  12112.  
  12113.        :'<text>'    Metacommand is a string.
  12114.  
  12115.  String values in the metalanguage may be either a literal string or string
  12116.  constant identifier. Constant expressions are not allowed for either
  12117.  numbers or strings, although you can achieve the same effect by declaring a
  12118.  constant identifier equal to the expression and using the identifier in the
  12119.  metacommand.
  12120.  
  12121.  In metacommands only, Boolean and enumerated constants are changed to
  12122.  their ORD values. Thus, a Boolean false value becomes 0 and true becomes 1.
  12123.  
  12124.  A complete alphabetical listing of MS-Pascal metacommands is given in
  12125.  Appendix G, "Summary of Microsoft Pascal Metacommands."
  12126.  
  12127.  
  12128.  18.1  Language Level Setting and Optimization
  12129.  
  12130.  
  12131.  The metacommands shown in Table 18.2 let you control the level (standard,
  12132.  extend, or system) at which the compiler processes your program and
  12133.  the degree to which optimization is used. Some of these metacommands
  12134.  may not be implemented in your version of the compiler. See Appendix B,
  12135.  "Version Specifics," in your Microsoft Pascal Compiler User's Guide for
  12136.  details.
  12137.  
  12138.  
  12139.  Table 18.2
  12140.  Language and Optimization Level
  12141. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  12142.  Name           Description
  12143.  ───────────────────────────────────────────────────────────────────────────
  12144.  $decmath       Directs the compiler to use the decimal
  12145.                 math routines in the auxiliary decimal
  12146.                 math runtime library.
  12147.  
  12148.  $extend        Adds extend level features
  12149.  
  12150.  $floatcalls    Directs the compiler to make calls to
  12151.                 the real number math routines; set to
  12152.                 $floatcalls+ by default
  12153.  
  12154.  $integer:<n>   Sets the length of the INTEGER type
  12155.  
  12156.  $real:<n>      Sets the length of the REAL type
  12157.  
  12158.  $rom           Gives a warning on static initialization
  12159.  
  12160.  $simple        Disables global optimizations
  12161.  Name           Description
  12162. $simple        Disables global optimizations
  12163.  
  12164.  $size          Minimizes size of code generated
  12165.  
  12166.  $speed         Minimizes execution time of code
  12167.  
  12168.  $standard      Enables standard level only
  12169.  
  12170.  $system        Adds extend and system level features
  12171.  
  12172.  The compiler issues a warning message if it encounters a feature whose
  12173.  level is not enabled. The default setting is $extend, which permits
  12174.  structured extensions that are relatively safe and portable. It also
  12175.  requires you to explicitly request $system extensions, which are by their
  12176.  nature low level, machine dependent, and relatively unstructured.
  12177.  
  12178.  $Integer and $real set the length (i.e., precision) of the standard
  12179.  INTEGER and real data types. $Integer takes an integer parameter, which
  12180.  must 2 or 4. However, you may set $real to either 4, or 8 (the default),
  12181.  to make type REAL identical to REAL4 or REAL8, respectively.
  12182.  
  12183.  The effect of the $size and $speed metacommands varies with the
  12184.  version of the optimizer in your implementation of the compiler. The
  12185.  default is $size. If you select $simple, no optimization of any kind is
  12186.  done. $Size, $speed, and $simple are all mutually exclusive.
  12187.  
  12188.  If $rom is set, the compiler gives a warning that static data will
  12189.  not be initialized in either of the following situations:
  12190.  
  12191.      1.  at a VALUE section
  12192.  
  12193.      2.  every place where static data initialization occurs due to $initck
  12194.          (described in Section 18.2, "Debugging and Error Handling")
  12195.  
  12196.  $Decmath+ directs the compiler to make calls to the decimal math support
  12197.  routines in which decimal floating-point numbers up to 14 digits and within
  12198.  a limited exponent range can be represented exactly. The results of the
  12199.  operations on the numbers in this format are also represented exactly if
  12200.  they are in the allowable range. If $decmath+ is used, it must precede any
  12201.  program text and may not be switched on and off.
  12202.  
  12203.  See your Microsoft Pascal Compiler User's Guide for any special
  12204.  instructions you must follow to use the decimal math package on your
  12205.  system.
  12206.  
  12207.  $Floatcalls+ generates calls to a real math runtime package to carry out
  12208.  floating-point operations. The $floatcalls- metacommand directs the
  12209.  compiler to generate in-line instruction "skeletons" for floating-point
  12210.  operations.
  12211.  
  12212.  
  12213.  18.2  Debugging and Error Handling
  12214.  
  12215.  
  12216.  The metacommands shown in Table 18.3 are for debugging and error
  12217.  handling. They also generate code to check for runtime errors.
  12218.  
  12219.  
  12220.  Table 18.3
  12221.  Debugging and Error Handling
  12222. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  12223.  Metacommand    Description
  12224.  Metacommand    Description
  12225.  ───────────────────────────────────────────────────────────────────────────
  12226.  $brave+        Sends error messages and warnings to the
  12227.                 terminal screen
  12228.  
  12229.  $debug-        Turns on or off all the debug checking
  12230.                 (CK in metacommands below); off by
  12231.                 default
  12232.  
  12233.  $entry-        Generates procedure entry/exit calls for
  12234.                 debugger
  12235.  
  12236.  $errors:<n>    Sets number of errors allowed per page
  12237.                 (default is 25)
  12238.  
  12239.  $goto-         Flags GOTO statements as "considered
  12240.                 harmful"
  12241.  
  12242.  $indexck-      Checks for array index values in range,
  12243.                 including super array indices; off by
  12244.                 default
  12245.  Metacommand    Description
  12246.                default
  12247.  
  12248.  $initck-       Checks for use of uninitialized values;
  12249.                 off by default
  12250.  
  12251.  $line-         Generates line number calls for the
  12252.                 debugger
  12253.  
  12254.  $mathck-       Checks for mathematical errors such as
  12255.                 overflow and division by zero; off by
  12256.                 default
  12257.  
  12258.  $nilck-        Checks for bad pointer values; off by
  12259.                 default
  12260.  
  12261.  $rangeck-      Checks for subrange validity; off by
  12262.                 default
  12263.  
  12264.  $runtime-      Determines context of runtime errors
  12265.  
  12266.  Metacommand    Description
  12267. 
  12268.  $stackck-      Checks for stack overflow at procedure
  12269.                 or function entry; off by default
  12270.  
  12271.  $tagck-        Checks tag fields in variant records;
  12272.                 off by default.
  12273.  
  12274.  $warn+         Gives warning messages in listing file
  12275.  
  12276.  If any check is on when the compiler processes a statement, tests relevant
  12277.  to the statement are done. A runtime error invokes a call to the
  12278.  runtime support routine, EMSEQQ (synonymous with ABORT). When EMSEQQ is
  12279.  called, the compiler passes the following information to it:
  12280.  
  12281.      1.  an error message
  12282.  
  12283.      2.  a standard error code
  12284.  
  12285.      3.  an optional error status value, such as an operating system return
  12286.          code
  12287.  
  12288.  EMSEQQ also has available:
  12289.  
  12290.      1.  the program counter at the location of the error
  12291.  
  12292.      2.  the stack pointer at the location of the error
  12293.  
  12294.      3.  the frame pointer at the location of the error
  12295.  
  12296.      4.  the current line number (if $line is on)
  12297.  
  12298.      5.  the current procedure or function name and the source filename in
  12299.          which the procedure or function was compiled (if $entry is on)
  12300.  
  12301.  Each of these metacommands is discussed in more detail on the
  12302.  following pages. Most of the metacommands in this group may also be given
  12303.  as command line switches to the compiler. See Section 18.6, "Command Line
  12304.  Switches," for details.
  12305.  
  12306.  
  12307.  $brave+
  12308.  
  12309.      Sends error messages and warnings to your terminal (in addition to
  12310.      writing them to the listing file). If the number of errors and
  12311.      warnings is more than will fit on the screen, the earlier ones scroll
  12312.      off and you will have to check the listing file to see them all.
  12313.  
  12314.  
  12315.  $debug-
  12316.  
  12317.      Turns on or off all of the debug switches (i.e., those that end with
  12318.      "CK"). You may find it useful to use $debug- at the beginning of a
  12319.      program to turn all checking off and then selectively turn on only the
  12320.      debug switches you want. Alternatively, you may use this metacommand
  12321.      to turn all debugging on at the start and then selectively turn off
  12322.      those you don't need as the program progresses. By default, some error
  12323.      checks are on and some off.
  12324.  
  12325.  
  12326.  $entry-
  12327.  
  12328.      Generates procedure and function entry and exit calls. This lets a
  12329.      debugger or error handler determine the procedure or function in which
  12330.      an error has occurred. Since this switch generates a substantial
  12331.      amount of extra code for each procedure and function, you should use it
  12332.      only when debugging. Note that $line+ requires $entry+; thus, $line+
  12333.      turns on $entry, and $entry- turns off $line.
  12334.  
  12335.  
  12336.  $errors:n
  12337.  
  12338.      Sets an upper limit for the number of errors allowed per page.
  12339.      Compilation terminates if that number is exceeded. The default is 25
  12340.      errors and/or warnings per page.
  12341.  
  12342.  
  12343.  $goto-
  12344.  
  12345.      Flags GOTO statements with a warning that they are "considered
  12346.      harmful." This warning may be useful in either of the following
  12347.      circumstances:
  12348.  
  12349.      1.  to encourage structured programming in an educational environment
  12350.  
  12351.      2.  to flag all GOTO statements during the process of debugging
  12352.  
  12353.  
  12354.  $indexck-
  12355.  
  12356.      Checks that array index values, including super array indices, are in
  12357.      range. Since array indexing occurs so often, bounds checking is
  12358.      enabled separately from other subrange checking.
  12359.  
  12360.  
  12361.  $initck-
  12362.  
  12363.      Checks for the occurrence of uninitialized values, such as the
  12364.      following:
  12365.  
  12366.      1.  uninitialized INTEGERs and 2-byte INTEGER subranges with the
  12367.          hexadecimal value 16#8000
  12368.  
  12369.      2.  uninitialized 1-byte INTEGER subranges with the hexadecimal value
  12370.          16#80
  12371.  
  12372.      3.  uninitialized pointers with the value 1 (if $nilck is also on)
  12373.  
  12374.      4.  uninitialized REALs with a special value
  12375.  
  12376.      The $initck metacommand generates code to perform the following
  12377.      actions:
  12378.  
  12379.      1.  set such values uninitialized when they are allocated
  12380.  
  12381.      2.  set the value of INTEGER range FOR-loop control variables
  12382.          uninitialized when the loop terminates normally
  12383.  
  12384.      3.  set the value of a function that returns one of these types
  12385.          uninitialized when the function is entered
  12386.  
  12387.      $Initck never generates any initialization or checking for WORD or
  12388.      address types. Statically allocated variables are loaded with their
  12389.      initial values. Also, $initck does not check values in an array or
  12390.      record when the array or record itself is used.
  12391.  
  12392.      Variables allocated on the stack or in the heap are assigned initial
  12393.      values with generated code. $Initck does not initialize any of the
  12394.      following classes of variables:
  12395.  
  12396.      1.  variables mentioned in a VALUE section
  12397.  
  12398.      2.  variant fields in a record
  12399.  
  12400.      3.  components of a super array allocated with the NEW procedure
  12401.  
  12402.  
  12403.  $line-
  12404.  
  12405.      Generates a call to a debugger or error handler for each source line
  12406.      of executable code. This allows the debugger to determine the number
  12407.      of the line in which an error has occurred. Because this metacommand
  12408.      generates a substantial amount of extra code for each line in a
  12409.      program, you should turn it on only when debugging. Note that $line+
  12410.      requires $entry+, so $line+ turns on $entry, and $entry- turns off
  12411.      $line.
  12412.  
  12413.  
  12414.  $mathck-
  12415.  
  12416.      Checks for mathematical errors, including INTEGER and WORD overflow
  12417.      and division by zero. $Mathck does not check for an INTEGER result of
  12418.      exactly -MAXINT-1 (i.e., #8000); $initck does catch this value if it is
  12419.      assigned and later used.
  12420.  
  12421.      Turning $mathck off does not always disable overflow checking. There
  12422.      are, however, library routines that provide addition and multiplication
  12423.      functions that permit overflow (LADDOK, LMULOK, SADDOK, SMULOK, UADDOK,
  12424.      and UMULOK). See Section 15.2, "Directory of Functions and
  12425.      Procedures," for descriptions of each of these functions.
  12426.  
  12427.  
  12428.  $nilck-
  12429.  
  12430.      Checks for the following conditions:
  12431.  
  12432.      1.  dereferenced pointers whose values are NIL
  12433.  
  12434.      2.  uninitialized pointers if $initck is also on
  12435.  
  12436.      3.  pointers that are out of range
  12437.  
  12438.      4.  pointers that point to a free block in the heap
  12439.  
  12440.      $Nilck occurs whenever a pointer is dereferenced or passed to the
  12441.      DISPOSE procedure. $Nilck does not check operations on address types.
  12442.  
  12443.  
  12444.  $rangeck-
  12445.  
  12446.      Checks subrange validity in the following circumstances:
  12447.  
  12448.      1.  assignment to subrange variables
  12449.  
  12450.      2.  CASE statements without an OTHERWISE clause
  12451.  
  12452.      3.  actual parameters for the CHR, SUCC, and PRED functions
  12453.  
  12454.      4.  indices in PACK and UNPACK procedures
  12455.  
  12456.      5.  set and LSTRING assignments and value parameters
  12457.  
  12458.      6.  super array upper bounds passed to the NEW procedure
  12459.  
  12460.  
  12461.  $runtime-
  12462.  
  12463.      If the $runtime switch is on when a procedure or function is
  12464.      compiled, the "location of an error" is the place where the procedure
  12465.      or function was called rather than the location in the procedure or
  12466.      function itself. This information is normally sent to your terminal,
  12467.      but you could link in a custom version of EMSEQQ, the error message
  12468.      routine, to do something different (such as invoke the runtime debugger
  12469.      or reset a controller). For more information on error handling, see
  12470.      Chapter 10, "Advanced Topics," in your Microsoft Pascal Compiler
  12471.      User's Guide.
  12472.  
  12473.  
  12474.  $stackck-
  12475.  
  12476.      Checks for stack overflow when entering a procedure or function and
  12477.      when pushing parameters larger than four bytes on the stack. In some
  12478.      implementations, stack overflow is always checked. In some
  12479.      implementations, stack overflow is never checked in procedures with the
  12480.      INTERRUPT attribute.
  12481.  
  12482.  
  12483.  $tagck-
  12484.  
  12485.      Checks tag values when accessing a variant field. Only those tag
  12486.      fields with identifiers (i.e., whose value is actually stored in the
  12487.      record) are checked.
  12488.  
  12489.  
  12490.  $warn+
  12491.  
  12492.      Sends warning messages to the listing file (this is the default). If
  12493.      this switch is turned off, only fatal errors are printed in the source
  12494.      listing.
  12495.  
  12496.  
  12497.  18.3  Source file control
  12498.  
  12499.  
  12500.  A small group of metacommands provide some measure of control over the use
  12501.  of the source file during compilation. These commands are listed in Table
  12502.  18.4 and described in more detail below.
  12503.  
  12504.  
  12505.  Table 18.4
  12506.  Source File Control
  12507. ╓┌─────────────────────┌─────────────────────────────────────────────────────╖
  12508.  Name                  Description
  12509.  ───────────────────────────────────────────────────────────────────────────
  12510.  $if constant          Allows conditional compilation
  12511.    $then text1         of text1 source if constant
  12512.    $else text2         is greater than zero
  12513.  $end
  12514.  
  12515.  $include:'filename'   Switches compilation from
  12516.                        current source file to source
  12517.                        file named
  12518.  Name                  Description
  12519.                       file named
  12520.  
  12521.  $inconst:text         Allows interactive setting
  12522.                        of constant values at
  12523.                        compile time
  12524.  
  12525.  $message:'text'       Allows the display of a message
  12526.                        to the terminal screen to indicate
  12527.                        which version of a program is
  12528.                        compiling
  12529.  
  12530.  $pop                  Restores saved value of all
  12531.                        metacommands
  12532.  
  12533.  $push                 Saves current value of all
  12534.                        metacommands
  12535.  
  12536.  Because the compiler keeps one look-ahead symbol, it actually
  12537.  processes metacommands that follow a symbol before it processes the symbol
  12538.  itself. This characteristic of the compiler can be a factor in cases such
  12539.  as the following:
  12540.  
  12541.       CONST Q = 1;
  12542.       {$if q $then}
  12543.       {Q is undefined in the $if.}
  12544.  
  12545.       CONST Q = 1; DUMMY = 0;
  12546.       {$if q $then}
  12547.       {Now Q is defined.}
  12548.       X := P^;
  12549.       {$nilck+}
  12550.       {NILCK applies to P^ here.}
  12551.  
  12552.       X := P^;;;
  12553.       {NILCK doesn't apply to P.}
  12554.       {$nilck-}
  12555.  
  12556.  Each of these metacommands is discussed in more detail on the
  12557.  following pages.
  12558.  
  12559.  
  12560.  $if constant $then text $end
  12561.  
  12562.      Allows for conditional compilation of a source text. If the
  12563.      value of the constant is greater than zero, then source text following
  12564.      the $if is processed; otherwise it is not. an $if $then $else
  12565.      construction is also available, as in the following example:
  12566.  
  12567.          {$if msdos $then}
  12568.          SECTOR = S12;
  12569.          {$else}
  12570.          SECTOR  = S128;
  12571.          {$end}
  12572.  
  12573.      To simulate an "if not" construction, use the following form of the
  12574.      metacommand:
  12575.  
  12576.  
  12577.          $if constant $else text $end
  12578.  
  12579.      The constant may be a literal number or constant identifier. The
  12580.      text between $then, $else, and $end is arbitrary; it can include line
  12581.      breaks, comments, other metacommands (including nested $ifs), etc. Any
  12582.      metacommands within skipped text are ignored, except, of course,
  12583.      corresponding $else or $end metacommands.
  12584.  
  12585.      Examples using the metaconditional:
  12586.  
  12587.          {$if FPCHIP $then}
  12588.            CODEGEN (FADDCALL, T1, LEFTP)
  12589.          {$end}
  12590.          {$if COMPSYS $else}
  12591.            IF USERSYS THEN DO_IT_TO_IT
  12592.          {$end}
  12593.  
  12594.  
  12595.  $include
  12596.  
  12597.      Allows the compiler to switch processing from the current source to
  12598.      the file named. When the end of the file that was included is reached,
  12599.      the compiler switches back to the original source and continues
  12600.      compilation. Resumption of compilation in the original source file
  12601.      begins with the line of source text that follows the line in which the
  12602.      $include occurred. Therefore, the $include metacommand should always be
  12603.      last on a line.
  12604.  
  12605.  
  12606.  $inconst
  12607.  
  12608.      Allows you to enter the values of the constants (such as those used
  12609.      in $ifs) at compile time, rather than editing the source. This is
  12610.      useful when you use metaconditionals to compile a version of a source
  12611.      for a particular environment, customer, target processor, etc.
  12612.      Compilation may be either interactive or batch oriented. For example,
  12613.      the metacommand $inconst:year produces the following prompt for the
  12614.      constant YEAR:
  12615.  
  12616.          Inconst : YEAR =
  12617.  
  12618.      You need only give a response like:
  12619.  
  12620.          Inconst : YEAR = 1983
  12621.  
  12622.      The response is presumed to be of type WORD. The effect is to
  12623.      declare a constant identifier named YEAR with the value 1983. This
  12624.      interactive setting of the constant YEAR is equivalent to the constant
  12625.      declaration:
  12626.  
  12627.  
  12628.          CONST YEAR = 1983;
  12629.  
  12630.      You may also respond with a quoted string literal to create a
  12631.      constant of type STRING (n). For example, the source file metacommand
  12632.      $inconst:header prompts for a header. By enclosing a literal string
  12633.      constant in quotes, you declare a string constant:
  12634.  
  12635.          Inconst : HEADER = 'Processor Version 2.75'
  12636.  
  12637.  
  12638.  $message
  12639.  
  12640.      on
  12641.  Allows you to send messages to your terminal during compilation.
  12642.      This is particularly useful if you use metaconditionals extensively,
  12643.      for example, and need to know which version of a program is being
  12644.      compiled.
  12645.  
  12646.      Example of the $message metacommand:
  12647.  
  12648.          {$message:'Message on terminal screen!'}
  12649.  
  12650.  
  12651.  $push and $pop
  12652.  
  12653.      Allow you to create a meta-environment you can store with $push
  12654.      and invoke with $pop. $Push and $pop are useful in $include files for
  12655.      saving and restoring the metacommands in the main source file.
  12656.  
  12657.  
  12658.  18.4  Listing File Control
  12659.  
  12660.  
  12661.  The metacommands listed in Table 18.5 and described in this section
  12662.  allow you to format the listing file as you wish.
  12663.  
  12664.  
  12665.  Table 18.5
  12666.  Listing File Control Metacommands
  12667. ╓┌─────────────────────┌─────────────────────────────────────────────────────╖
  12668.  Metacommand           Description
  12669.  ───────────────────────────────────────────────────────────────────────────
  12670.  $linesize:n           Sets width of listing. Default
  12671.                        is 79 or 131, depending on
  12672.                        implementation.
  12673.  
  12674.  $list+                Turns on or off source listing.
  12675.                        Errors are always listed.
  12676.  
  12677.  $ocode+               Turns on disassembled object code
  12678.                        listing.
  12679.  
  12680.  $page+                Skips to next page. Line number
  12681.                        is not reset.
  12682.  
  12683.  $page:n               Sets page number for next page
  12684.                        (does not skip to next page).
  12685.  
  12686.  Metacommand           Description
  12687. 
  12688.  $pageif:n             Skips to next page if less than n
  12689.                        lines left on current page.
  12690.  
  12691.  $pagesize:n           Sets length of listing in lines.
  12692.                        Default is 55.
  12693.  
  12694.  $skip:n               Skips n lines or to end of page.
  12695.  
  12696.  $subtitle:'text'      Sets page subtitle.
  12697.  
  12698.  $symtab+              Sends symbol table to listing
  12699.                        file.
  12700.  
  12701.  $title:'text'         Sets page title.
  12702.  
  12703.  
  12704.  $linesize:n
  12705.  
  12706.      Sets the maximum length of lines in the listing file. This
  12707.      value normally defaults to either 131 or 79, depending on the
  12708.      implementation. See Appendix B, "Version Specifics," in your
  12709.      Microsoft Pascal Compiler User's Guide for the default on your
  12710.      system.
  12711.  
  12712.  
  12713.  $list+
  12714.  
  12715.      Turns on the source listing. Except for $list-, metacommands
  12716.      themselves appear in the listing. The format of the listing file is
  12717.      described in Section 18.5, "Listing File Format."
  12718.  
  12719.  
  12720.  $ocode+
  12721.  
  12722.      Turns on the symbolic listing of the generated code to the object
  12723.      listing file. Although the format varies with the target code
  12724.      generator, it generally looks like an assembly listing, with code
  12725.      addresses and operation mnemonics. In many cases, the identifiers for
  12726.      procedure, function, and static variables are truncated in the object
  12727.      listing file.
  12728.  
  12729.  
  12730.  $page+
  12731.  
  12732.      Forces a new page in the source listing. The page number of the
  12733.      listing file is automatically incremented.
  12734.  
  12735.  
  12736.  $page:n
  12737.  
  12738.      Sets the page number of the next page of the source listing. $page:n
  12739.      does not force a new page in the listing file.
  12740.  
  12741.  
  12742.  $pageif:n
  12743.  
  12744.      Conditionally performs $page+, if the current line number of the
  12745.      source file plus n is less than or equal to the current page size.
  12746.  
  12747.  
  12748.  $pagesize:n
  12749.  
  12750.      Sets the maximum size of a page in the source listing. The default is
  12751.      55 lines per page.
  12752.  
  12753.  
  12754.  $skip:n
  12755.  
  12756.      Skips n lines or to the end of the page in the source listing.
  12757.  
  12758.  
  12759.  $subtitle:'subtitle'
  12760.  
  12761.      Sets the name of a subtitle that appears beneath the title at the top
  12762.      of each page of the source listing.
  12763.  
  12764.  
  12765.  $symtab+
  12766.  
  12767.      If on at the end of a procedure, function, or compiland, sends
  12768.      information about its variables to the listing file (for example, see
  12769.      lines 14 and 17 in the sample listing file in Section 18.5, "Listing
  12770.      File Format"). The left columns contain the following:
  12771.  
  12772.  
  12773.      1.  the offset to the variable from the frame pointer (for variables in
  12774.          procedures and functions)
  12775.  
  12776.      2.  the offset to the variable in the fixed memory area (for main
  12777.          program and STATIC variables)
  12778.  
  12779.      3.  the length of the variable
  12780.  
  12781.      A leading plus or minus sign indicates a frame offset.  Note that this
  12782.      offset is to the lowest address used by the variable.
  12783.  
  12784.      The first line of the $symtab listing contains the offset to the
  12785.      return address, from the top of the frame (zero for the main program),
  12786.      and the length of the frame, from the framepointer to the end including
  12787.      front end temporary variables. Code generator temporary variables are
  12788.      not included.
  12789.  
  12790.      For functions, the second line contains the offset, length, and type
  12791.      of the value returned by the functions. The remaining lines list the
  12792.      variables, including their type and attribute keywords, as shown in the
  12793.      following list.
  12794.  
  12795.          Keyword   Meaning
  12796.          ───────────────────────────────────────────────────────────────────
  12797.          Public    Has the PUBLIC attribute
  12798.  
  12799.          Extern    Has the EXTERN attribute
  12800.  
  12801.          Origin    Has the ORIGIN attribute
  12802.  
  12803.          Static    Has the STATIC attribute
  12804.  
  12805.          Const     Has the READONLY attribute
  12806.  
  12807.          Value     Occurs in a VALUE section
  12808.  
  12809.          ValueP    Is a value parameter
  12810.  
  12811.          VarP      Is a VAR or CONST parameter
  12812.  
  12813.          VarsP     Is a VARS or CONSTS parameter
  12814.  
  12815.          ProcP     Is a procedural parameter
  12816.  
  12817.          Segmen    Uses segmented addressing
  12818.  
  12819.          Regist    Parameter passed in register
  12820.  
  12821.  
  12822.  $title:'title'
  12823.  
  12824.      Sets the name of a title that appears at the top of each page of the
  12825.      source listing.
  12826.  
  12827.  
  12828.  18.5  Listing File Format
  12829.  
  12830.  
  12831.  The following discussion of listing file format is keyed to this
  12832.  sample listing:
  12833.  
  12834.  Use   Title                                    PAGE   1
  12835.  User  Subtitle                                 12/11/82
  12836.                                                 10:49:17
  12837.  JG IC Line#  Source Line   MS-Pascal Version 3.0  10/82
  12838.     00     1  PROGRAM foo;   {$symtab+}
  12839.     10     2  VAR i : integer; K : ARRAY [-9..0] OF integer,
  12840.            2  --------------------Warning 156,Assumed ;^
  12841.     20     3  FUNCTION bar (VAR j : integer) : integer;
  12842.     20     4    VAR k : ARRAY [0..9] OF integer;
  12843.     20     5    BEGIN
  12844.  +  21     6    GOTO 1;         {jump forward}
  12845.            6  -------^Warning 281 Label Assumed Declared
  12846.   = 21     7     i := bar (j);  {assign to global}
  12847.            8     1 :             {label}
  12848.   / 21     9     j := bar (i);  {global to VAR parm}
  12849.  -  21    10     GOTO 1;        {jump backward}
  12850.  *  21    11     RETURN; GOTO 1;{other jumps}
  12851.   % 21    12     i := bar (i);  {other global reference}
  12852.     21    13     j := bar (j);   {no global references}
  12853.     10    14    END;
  12854.           14  ----^306 Function Assignment Not Found
  12855.  
  12856.  Symtab   14  Offset Length Variable - BAR
  12857.               -    2     24 Return offset, Frame length
  12858.               -    2      2 (func'n return) : Integer
  12859.               +    4      2 J               : Integer VarP
  12860.               -   22     20 K               : Array
  12861.  
  12862.     10    15  BEGIN
  12863.     11    16   i := bar (i);
  12864.     00    17  END.
  12865.  
  12866.  Symtab   17  Offset Length Variable
  12867.                    0     24 Return offset, Frame length
  12868.                    2      2 I              : Integer
  12869.                    4     20 K              : Array
  12870.  
  12871.               Errors  Warns In Pass One
  12872.                    1      2
  12873.  
  12874.  Every page has a heading that includes such information as your title and
  12875.  subtitle, set with the metacommands $title and $subtitle,
  12876.  respectively. If these metacommands appear on the first source line,
  12877.  they take effect on the first page. The page number appears in the right
  12878.  side of the first line of the heading. In some versions, the date and time
  12879.  appear in the right side of the second and third line, respectively. You
  12880.  can set the page number with $page:n or start a new page with $page+.
  12881.  
  12882.  The fourth line of the listing contains the column labels. The
  12883.  contents of the first three columns are as follows:
  12884.  
  12885.      1.  The JG column
  12886.  
  12887.          The JG column contains flag characters generated for your
  12888.          information. Jump flags, which appear under the J, may contain one
  12889.          of the following characters:
  12890.  
  12891.          +    forward jump (BREAK or GOTO a label
  12892.               not yet encountered)
  12893.  
  12894.          -    backward jump (CYCLE or GOTO a label
  12895.               already encountered)
  12896.  
  12897.          *    other jumps (RETURN or a mixture of
  12898.               jumps)
  12899.  
  12900.          Codes for global variables (not local to the current procedure or
  12901.          function) appear in the column under G:
  12902.  
  12903.          =    assignment to a nonlocal variable
  12904.  
  12905.          /    passing a nonlocal variable as a
  12906.               reference parameter
  12907.  
  12908.          %    a combination of the two
  12909.  
  12910.      2.  The IC column
  12911.  
  12912.          The IC column contains information about the current nesting
  12913.          levels. The digit under the I refers to the identifier (scope)
  12914.          level, which changes with procedure and function declarations, as
  12915.          well as with record declarations and WITH statements. The digit in
  12916.          the C column refers to the control statement level; this number
  12917.          changes with BEGIN and END pairs, as well as with CASE and END and
  12918.          REPEAT and UNTIL pairs. The number in this column is useful for
  12919.          finding missing END keywords.
  12920.  
  12921.          If a line is not actively used by the compiler, all these columns
  12922.          are blank. Thus you can locate a portion of the source
  12923.          accidentally commented out or skipped due to an $if and $end pair.
  12924.  
  12925.      3.  The Line column
  12926.  
  12927.          The Line column shows the line number of the line in the
  12928.          source file. An $included file gets its own sequence of line
  12929.          numbers. If $line is on, this line number and the source file name
  12930.          identify runtime errors.
  12931.  
  12932.  Two kinds of compiler messages appear in the listing:  errors and
  12933.  warnings. A compilation with any errors cannot generate code. A compilation
  12934.  with warnings only can generate code, but the result may not execute
  12935.  correctly. Warnings start with the word "Warning" and a number (see, for
  12936.  example, line 2 in the sample listing). Errors start with an error number
  12937.  (see line 14 in the sample listing).
  12938.  
  12939.  You can suppress warning messages with the metacommand $warn-, but
  12940.  this is not generally recommended. The metacommand $brave+ sends
  12941.  error and warning messages to your terminal (as well as to the listing
  12942.  file). However, if there are more than will fit on a single screen, the
  12943.  first ones will scroll off.
  12944.  
  12945.  The location of the error is indicated in the listing file with an up
  12946.  arrow (^). The message itself may appear to the left or right of the arrow
  12947.  and is preceded with a dashed line.
  12948.  
  12949.  Sometimes, the compiler does not detect an error until after the
  12950.  listing of the following line. In this case, the error message line number
  12951.  is not in sequence. Tabs are allowed in the source and are passed on to
  12952.  the listing unchanged. If the tab spacing is every eight columns, the error
  12953.  pointer (^) is generally correct. However, an error pointer near the end of
  12954.  a line may be displaced if the following line has tabs.
  12955.  
  12956.  If the compiler encounters an error from which it cannot recover, it
  12957.  gives the message "Compiler Cannot Continue!". This message appears if any
  12958.  of the following occurs:
  12959.  
  12960.      1.  The keyword PROGRAM (or IMPLEMENTATION, INTERFACE, or MODULE) is
  12961.          not found, or the program, module, or unit identifier is missing.
  12962.  
  12963.      2.  The compiler encounters an unexpected end-of-file.
  12964.  
  12965.      3.  The compiler finds too many errors; the maximum number of errors
  12966.          per page is set with the $errors metacommand (the default is 25).
  12967.  
  12968.      4.  The identifier scope becomes too deeply nested. (See Appendix B,
  12969.          "Version Specifics," in your Microsoft Pascal Compiler User's Guide
  12970.          for the nesting level limit for your implementation.)
  12971.  
  12972.  When the compiler is unable to continue, for whatever reason, it simply
  12973.  writes the rest of the program to the listing file with very little
  12974.  error checking.
  12975.  
  12976.  
  12977.  
  12978.  Appendices
  12979.  
  12980.  ───────────────────────────────────────────────────────────────────────────
  12981.  
  12982.  A     Pascal Syntax Diagrams
  12983.  
  12984.  B     Microsoft Pascal Features and the ISO Standard
  12985.  
  12986.  C     Microsoft Pascal and Other Pascals
  12987.  
  12988.  D     ASCII Character Codes
  12989.  
  12990.  E     Summary of Microsoft Pascal Reserved Words
  12991.  
  12992.  F     Summary of Available Procedures and Functions
  12993.  
  12994.  G     Summary of Microsoft Pascal Metacommands
  12995.  
  12996.  
  12997.  
  12998.  Appendix A  Pascal Syntax Diagrams
  12999.  
  13000.  ───────────────────────────────────────────────────────────────────────────
  13001.  
  13002.  The diagrams on the following pages show the fundamental syntax of the
  13003.  Microsoft Pascal language. They are arranged in the order that you would be
  13004.  likely to use the elements while writing a program. The meaning of the
  13005.  differently shaped outlines is as follows:
  13006.  
  13007.      1.  Rectangles
  13008.  
  13009.          Indicate reserved words or symbols of the MS-Pascal language. These
  13010.          must be typed as shown.
  13011.  
  13012.      2.  Double-lined rectangles
  13013.  
  13014.          Indicate higher-level constructions that usually have syntax
  13015.          diagrams of their own.
  13016.  
  13017.      3.  High boxes with double lines at top and bottom
  13018.  
  13019.          Indicate punctuation that is required and must be typed as shown.
  13020.  
  13021.      4.  Arrows
  13022.  
  13023.          Help to show the path through the diagram, including any possible
  13024.          looping (i.e., repetition of syntax elements).
  13025.  
  13026.  
  13027.  Source File
  13028.                       ┌────────────────────────────┐
  13029.          ┌─────────┐  │  ╒═╕     ╔══════╗     ╒═╕  │  ╒═╕     ┌────┐
  13030.  ───┬─┬─│INTERFACE├──┴─│(├────║number╟────│)├──┴─│;├────│UNIT├─┐
  13031.     │ │  └─────────┘     ╘═╛     ╚══════╝     ╘═╛     ╘═╛     └────┘ │
  13032.     │ │       ┌──────────────────────────────────────────────────────┘
  13033.     │ │       │ ╔══════════╗     ╒═╕     ╔══════════╗     ╒═╕    ╒═╕
  13034.     │ │       └║identifier╟────│(├──┬─║identifier╟──┬─│)├───│;├─┐
  13035.     │ │         ╚══════════╝     ╘═╛  │  ╚══════════╝  │  ╘═╛    ╘═╛ │
  13036.     │ │                               │      ╒═╕       │             │
  13037.     │ │                               └──────┤,│──────┘             │
  13038.     │ │                                      ╘═╛                     │
  13039.     │ │ ┌────────────┬───────────────────────────────────────────────┘
  13040.     │ │ │            │                  ┌───────────┐
  13041.     │ │ │ ╔═══════╗  │  ╔════════════╗  │  ┌─────┐  │  ┌───┐     ╒═╕
  13042.     │ │ └║uselist╟──┴─║declarations╟──┴─│BEGIN├──┴─│END├────│;├─┐
  13043.     │ │   ╚═══════╝     ╚════════════╝     └─────┘     └───┘     ╘═╛ │
  13044.     ├─┴──────────────────────────────────────────────────────────────┘
  13045.     │                                 ┌───────────────────────────────┐
  13046.     │    ╔═══════╗      ╔══════════╗  │  ╒═╕     ╔══════════╗     ╒═╕ │
  13047.     ├───║PROGRAM╟─────║identifier╟──┴─│(├──┬─║identifier╟──┬─│)├─┴─┐
  13048.     │    ╚═══════╝      ╚══════════╝     ╘═╛  │  ╚══════════╝  │  ╘═╛   │
  13049.     │                                         │      ╒═╕       │        │
  13050.     │                                         └──────┤,│──────┘        │
  13051.     │                                                ╘═╛                │
  13052.     │    ┌──────────────┐     ┌──┐     ╔══════════╗                     │
  13053.     ├───│IMPLEMENTATION├────│OF├────║identifier╟─────────────────────┤
  13054.     │    └──────────────┘     └──┘     ╚══════════╝                     │
  13055.     │                                 ┌─────────────────┐               │
  13056.     │      ┌──────┐     ╔══════════╗  │  ╔══════════╗   │               │
  13057.     └─────│MODULE├────║identifier╟──┴─║attributes╟───┴───────────────┤
  13058.            └──────┘     ╚══════════╝     ╚══════════╝                   │
  13059.                                               ╒═╕                       │
  13060.     ┌───────────────────────┬─────────────────┤;│──────────────────────┘
  13061.     │                       │                 ╘═╛
  13062.     │            ╔═══════╗  │  ╔════════════╗
  13063.     └───────────║uselist╟──┴─║declarations╟───────────────────────────┐
  13064.                  ╚═══════╝     ╚════════════╝                           │
  13065.     ┌────────────────────────────┬──────────────────────────────────────┘
  13066.     │   ┌─────┐     ╔═════════╗  │  ┌───┐     ╒═╕
  13067.     └──│BEGIN├──┬─║statement╟─┬┴─│END├────│.├───────────────────────
  13068.         └─────┘  │  ╚═════════╝ │   └───┘     ╘═╛
  13069.                  │      ╒═╕     │
  13070.                  └──────┤;│────┘
  13071.                         ╘═╛
  13072.  
  13073.  
  13074.  Identifier
  13075.           ╔══════╗
  13076.  ────────║letter╟─────────────────┬──────────────┬─────────────────────
  13077.           ╚══════╝                 │   ╔══════╗   │
  13078.                                    ├───╢letter║──┤
  13079.                                    │   ╚══════╝   │
  13080.                                    │   ╔═════╗    │
  13081.                                    ├───╢digit║───┤
  13082.                                    │   ╚═════╝    │
  13083.                                    │     ╒═╕      │
  13084.                                    └─────┤-│─────┘
  13085.                                          ╘═╛
  13086.  
  13087.  
  13088.  Number
  13089.                                              ╔═════╗
  13090.  ───────┬───────────────────────────┬─────┬─║digit╟──┬─────────────────
  13091.         │                      ╒═╕  │     │  ╚═════╝  │
  13092.         └────┬────────────┬───│#├──┘     └───────────┘
  13093.              │  ╔═════╗   │    ╘═╛
  13094.              └──╢digit║──┘
  13095.                 ╚═════╝
  13096.  
  13097.  
  13098.  Label
  13099.                                 ╔══════════╗
  13100.                            ┌───║identifier╟───┐
  13101.                            │    ╚══════════╝   │
  13102.                            │      ╔═════╗      │
  13103.  ──────────────────────────┴───┬─║digit╟──┬───┴────────────────────────
  13104.                                │  ╚═════╝  │
  13105.                                └───────────┘
  13106.  
  13107.  
  13108.  Uselist
  13109.                                  ┌────────────────────────────────┐
  13110.       ┌────┐      ╔══════════╗   │  ╒═╕     ╔══════════╗      ╒═╕ │
  13111.  ──┬─│USES├───┬─║identifier╟───┴─│(├──┬─║identifier╟───┬─│)├─┴─┬───
  13112.    │  └────┘   │  ╚══════════╝      ╘═╛  │  ╚══════════╝   │  ╘═╛   │
  13113.   ╒╧╕         ╒╧╕                        │      ╒═╕        │        │
  13114.   │;│         │,│                        └──────┤,│───────┘        │
  13115.   ╘═╛         ╘═╛                               ╘═╛                 │
  13116.                                                                   │
  13117.    └───────────┴────────────────────────────────────────────────────┘
  13118.  
  13119.  
  13120.  Declarations
  13121.  ─┬──────────────────────────────────────────────────────────────────┬──
  13122.   ├──────────────────────────────────────────────────────────────────┤
  13123.   │     ┌─────┐                  ╔═════╗                    ╒═╕      │
  13124.   ├────│LABEL├───────────────┬─║label╟──┬────────────────│;├──────┤
  13125.   │     └─────┘               │  ╚═════╝  │                 ╘═╛      │
  13126.   │                           │    ╒═╕    │                          │
  13127.   │                           └────┤,│───┘                          │
  13128.   │                                ╘═╛                               │
  13129.   │  ┌─────┐      ╔══════════╗     ╒═╕     ╔══════════╗      ╒═╕     │
  13130.   ├─│CONST├───┬─║identifier╟────│=├────║expression╟─────│;├──┬──┤
  13131.   │  └─────┘   │  ╚══════════╝     ╘═╛     ╚══════════╝      ╘═╛  │  │
  13132.   │            └──────────────────────────────────────────────────┘  │
  13133.   │     ┌────┐     ╔══════════╗     ╒═╕     ╔════╗      ╒═╕          │
  13134.   ├────│TYPE├──┬─║identifier╟────│=├────║type╟─────│;├───────┬──┤
  13135.   │     └────┘  │  ╚══════════╝     ╘═╛     ╚════╝      ╘═╛       │  │
  13136.   │             └─────────────────────────────────────────────────┘  │
  13137.   │      ┌───┐                         ╔══════════╗                  │
  13138.   ├─────│VAR├────────┬───────────────║attributes╟───────────────┐  │
  13139.   │      └───┘        │                ╚══════════╝               │  │
  13140.   │ ┌─────────────────┴───────────────────────────────────────────┘  │
  13141.   │ │                 ┌───────────────┐                              │
  13142.   │ │   ╔══════════╗  │  ╔══════════╗ │   ╒═╕     ╔════╗      ╒═╕    │
  13143.   │ ├──║identifier╟──┴─║attributes╟─┴┬─│:├────║type╟─────│;├─┬──┤
  13144.   │ │   ╚══════════╝     ╚══════════╝  │  ╘═╛     ╚════╝      ╘═╛ │  │
  13145.   │ │                 ╒═╕              │                          │  │
  13146.   │ ├─────────────────┤,│─────────────┘                          │  │
  13147.   │ │                 ╘═╛                                         │  │
  13148.   │ └─────────────────────────────────────────────────────────────┘  │
  13149.   │     ┌─────┐     ╔════════╗     ┌──┐     ╔══════════╗     ╒═╕     │
  13150.   ├────│VALUE├──┬─║variable╟────│:=├────║expression╟────│;├─┬───┤
  13151.   │     └─────┘  │  ╚════════╝     └──┘     ╚══════════╝     ╘═╛ │   │
  13152.   │              └───────────────────────────────────────────────┘   │
  13153.   │       ╔═══════╗                ╒═╕                 ╔════╗        │
  13154.   └──────║heading╟───────────────│;├────────────────║body╟────────┘
  13155.           ╚═══════╝                ╘═╛                 ╚════╝
  13156.  
  13157.  
  13158.  Heading
  13159.                ┌─────────┐               ╔══════════╗
  13160.  ───────────┬─│PROCEDURE├──┬───────────║identifier╟───────────────────┐
  13161.             │  └─────────┘  │            ╚══════════╝                   │
  13162.             │  ┌────────┐   │                                           │
  13163.             └─│FUNCTION├───┘                                           │
  13164.                └────────┘                                       ╒═╕     │
  13165.     ┌───────────────────────────────────────────────────────────┤(│────┤
  13166.     │      ┌───┐                                                ╘═╛     │
  13167.     │  ┌──│VAR├────┐                                                   │
  13168.     │  │   └───┘    │                                                   │
  13169.     │  │   ┌────┐   │                                                   │
  13170.     │  ├──│VARS├───┤                                                   │
  13171.     │  │   └────┘   │    ╔══════════╗    ╒═╕    ╔══════════╗      ╒═╕   │
  13172.     └┬─┼────────────┼─┬─║identifier╟─┬─│:├───║identifier╟─┬─┬─│)├───┤
  13173.      │ │  ┌─────┐   │ │  ╚══════════╝ │  ╘═╛    ╚══════════╝ │ │  ╘═╛   │
  13174.      │ ├─│CONST├───┤ │       ╒═╕     │                      │ │        │
  13175.      │ │  └─────┘   │ └───────┤,│────┘                      │ │        │
  13176.      │ │  ┌──────┐  │         ╘═╛                            │ │        │
  13177.      │ ├─│CONSTS├──┘                                        │ │        │
  13178.      │ │  └──────┘            ╔═══════╗                      │ │        │
  13179.      │ └─────────────────────║heading╟──────────────────────┘ │        │
  13180.      │                        ╚═══════╝                        │        │
  13181.      │                       ╒═╕                               │        │
  13182.      └───────────────────────┤;│──────────────────────────────┘        │
  13183.                              ╘═╛                                        │
  13184.      ┌──────────────────────────────────────────────────────────────────┘
  13185.      │
  13186.      └─┬───────────────────────────────┬────────┬────────────────┬──────
  13187.        │      ╒═╕        ╔══════════╗  │        │  ╔══════════╗  │
  13188.        └─────│:├───────║identifier╟──┘        └─║attributes╟──┘
  13189.               ╘═╛        ╚══════════╝              ╚══════════╝
  13190.  
  13191.  
  13192.  Attributes
  13193.         ┌─────────────────┬─────────────┬──────────────────┐
  13194.     ╒═╕ │    ╔══════════╗ │    ╔══════╗ │  ╒═╕    ╔══════╗ │   ╒═╕
  13195.  ──│[├─┴─┬─║identifier╟─┴───║number╟─┴─│:├───║number╟─┴┬─│]├────
  13196.     ╘═╛   │  ╚══════════╝      ╚══════╝    ╘═╛    ╚══════╝  │  ╘═╛
  13197.           │                       ╒═╕                       │
  13198.           └───────────────────────┤,│──────────────────────┘
  13199.                                   ╘═╛
  13200.  
  13201.  
  13202.  Type
  13203.  ───┬──────────────────┬───────────────────┬────────────────────┐       │
  13204.     │                ┌──┐      ┌──┐     ┌──┐     ┌──┐        ╒╕      │
  13205.     │                │ADR├─────│OF│     │ADS├────│OF│        ││      │
  13206.     │                └───┘      └┬─┘     └───┘     └┬─┘        ╘╤╛      │
  13207.     ├────────────────────────────┴──────────────────┴───────────┘       │
  13208.     │      ╔══════════╗                                                 │
  13209.     ├─────║identifier╟────────┬────────────────────────────────┬───────┤
  13210.     │      ╚══════════╝        │  ╒═╕     ╔══════════╗     ╒═╕  │       │
  13211.     │                          └─│(├──┬─║expression╟──┬─│)├──┘       │
  13212.     │                             ╘═╛  │  ╚══════════╝  │  ╘═╛          │
  13213.     │                                  │       ╒═╕      │               │
  13214.     │                                  └───────┤,│─────┘               │
  13215.     │                                          ╘═╛                      │
  13216.     │             ╒═╕          ╔══════════╗           ╒═╕               │
  13217.     ├────────────│(├─────┬───║identifier╟────┬─────│)├───────────────┤
  13218.     │             ╘═╛     │    ╚══════════╝    │      ╘═╛               │
  13219.     │                     │        ╒═╕         │                        │
  13220.     │                     └────────┤,│────────┘                        │
  13221.     │                              ╘═╛                                  │
  13222.     │          ╔══════════╗        ╒══╕       ╔══════════╗              │
  13223.     ├─────────║expression╟───────│..├──────║expression╟──────────────┤
  13224.     │          ╚══════════╝        ╘══╛       ╚══════════╝              │
  13225.     ├───────────┬────────────┬──────┬──────────────┬─────────────┐      │
  13226.     │           │   ┌─────┐  │      │   ┌──────┐   │             │      │
  13227.     │           └──│SUPER├──┘      └──│PACKED├───┘             │      │
  13228.     │               └─────┘             └──────┘                 │      │
  13229.     ├────────────────────────────────────────────────────────────┘      │
  13230.     │               ┌─────┐                    ╒═╕                      │
  13231.     ├──────────────│ARRAY├───────────────────│[├───────────────┐      │
  13232.     │               └─────┘                    ╘═╛               │      │
  13233.     │      ┌─────────────────────────────────────────────────────┘      │
  13234.     │      │     ╔══════════╗   ╒══╕   ╒═╕      ╒═╕    ┌──┐     ╔════╗  │
  13235.     │      └┬─┬─║expression╟──│..├──│*├─┬─┬─│]├───│OF├────║type╟──┤
  13236.     │       │ │  ╚══════════╝   ╘══╛   ╘═╛ │ │  ╘═╛    └──┘     ╚════╝  │
  13237.     │       │ │           ╔════╗           │ │                          │
  13238.     │       │ └──────────║type╟───────────┘ │                          │
  13239.     │       │             ╚════╝             │                          │
  13240.     │       │               ╒═╕              │                          │
  13241.     │       └───────────────┤,│─────────────┘                          │
  13242.     │          ┌──────┐     ╘═╛        ╔══════╗          ┌───┐          │
  13243.     ├─────────│RECORD├───────────────║fields╟─────────│END├──────────┤
  13244.     │          └──────┘                ╚══════╝          └───┘          │
  13245.     │         ┌───┐                  ┌──┐              ╔════╗           │
  13246.     ├────────│SET├─────────────────│OF├─────────────║type╟───────────┤
  13247.     │         └───┘                  └──┘              ╚════╝           │
  13248.     │         ┌────┐                 ┌──┐              ╔════╗           │
  13249.     └────────│FILE├────────────────│OF├─────────────║type╟───────────┘
  13250.               └────┘                 └──┘              ╚════╝
  13251.  
  13252.  
  13253.  Fields
  13254.          ╔══════════╗                                          ╒═╕
  13255.  ─┬─┬─┬─║identifier╟───┬─────────────────────────────────┬─┬─│:├────────┐
  13256.   │ │ │  ╚══════════╝   │   ╒═╕     ╔══════════╗     ╒═╕  │ │  ╘═╛        │
  13257.   │ │ │                 └──│[├────║expression╟────│]├──┘ │             │
  13258.   │ │ │                     ╘═╛     ╚══════════╝     ╘═╛    │             │
  13259.   │ │ │                         ╒═╕                         │             │
  13260.   │ │ └─────────────────────────┤,│────────────────────────┘             │
  13261.   │ │              ╒═╕          ╘═╛       ╔════╗                          │
  13262.   ├─┴──────────────┤;│──────────┬────────╢type║─────────────────────────┘
  13263.   │                ╘═╛           │        ╚════╝
  13264.   ├──────────────────────────────┴────────────────────────────────────────┐
  13265.   │  ┌────┐  ╔══════════╗                             ╒═╕  ╔══════════╗   │
  13266.   └─│CASE├─║identifier╟─┬─────────────────────────┬│:├─║identifier╟─┐ │
  13267.      └────┘  ╚══════════╝ │ ╒═╕  ╔══════════╗  ╒═╕  │ ╘═╛  ╚══════════╝ │ │
  13268.                           └─┤[├─║expression╟─│]├──┘                   │ │
  13269.                             ╘═╛  ╚══════════╝  ╘═╛                      │ │
  13270.   ┌─────────────────────────────────────────────────────────────────────┘ │
  13271.   │  ┌──┐    ╔═════╗     ╒═╕      ╒═╕    ╔══════╗     ╒═╕                 │
  13272.   └─│OF├─┬─║cases╟────│:├─────│(├───║fields╟────│)├──┬─┬────────────┤
  13273.      └──┘ │  ╚═════╝     ╘═╛      ╘═╛    ╚══════╝     ╘═╛  │ │            │
  13274.           │                       ╒═╕                      │ │  ╒═╕       │
  13275.           └───────────────────────┤;│─────────────────────┘ └─│;├───────┴
  13276.                                   ╘═╛                           ╘═╛
  13277.  
  13278.  
  13279.  Body
  13280.      ┌─────────────────────────────────────────────────────────────┐
  13281.      │  ╔════════════╗    ┌─────┐    ╔═════════╗     ┌───┐     ╒═╕ │
  13282.  ────┼─║declarations╟───│BEGIN├─┬─║statement╟─┬──│END├──┬─│;├─┴────
  13283.      │  ╚════════════╝    └─────┘ │  ╚═════════╝ │   └───┘  │  ╘═╛
  13284.      │                            │      ╒═╕     │          │
  13285.      │                            └──────┤;│────┘          │
  13286.      │                                   ╘═╛                │
  13287.      │                                ┌──────┐              │
  13288.      ├───────────────────────────────│EXTERN├──────────────┤
  13289.      │                                └──────┘              │
  13290.      │                                ┌───────┐             │
  13291.      └───────────────────────────────│FORWARD├─────────────┘
  13292.                                       └───────┘
  13293.  
  13294.  
  13295.  Statement
  13296.                               ╔═════╗                      ╒═╕
  13297.  ───────────────┬────────────║label╟─────────────────────│:├────────┐
  13298.                 │             ╚═════╝                      ╘═╛        │
  13299.  ┌──────────────┴─────────────────────────────────────────────────────┘
  13300.  │        ╔════════╗                ┌──┐              ╔══════════╗
  13301.  ├───────║variable╟───────────────│:=├─────────────║expression╟─────┬
  13302.  │        ╚════════╝                └──┘              ╚══════════╝     │
  13303.  │                     ┌────────────────────────────────────────────┐  │
  13304.  │      ╔══════════╗   │      ╒═╕        ╔══════════╗         ╒═╕   │  │
  13305.  ├─────║identifier╟───┴─────│(├────┬──║expression╟───┬────│)├───┴──┤
  13306.  │      ╚══════════╝          ╘═╛    │   ╚══════════╝   │     ╘═╛      │
  13307.  │                                   │       ╒═╕        │              │
  13308.  │                                   └───────┤,│───────┘              │
  13309.  │         ┌─────┐              ╔═════════╗  ╘═╛       ┌───┐           │
  13310.  ├────────│BEGIN├──────────┬──║statement╟───┬───────│END├───────────┤
  13311.  │         └─────┘          │   ╚═════════╝   │        └───┘           │
  13312.  │                          │       ╒═╕       │                        │
  13313.  │                          └───────┤;│──────┘                        │
  13314.  │                                  ╘═╛                                │
  13315.  │            ╒═╕               ╔═════════╗                ╒═╕         │
  13316.  ├───────────│[├───────────┬──║statement╟───┬───────────│]├─────────┤
  13317.  │            ╘═╛           │   ╚═════════╝   │            ╘═╛         │
  13318.  │                          │       ╒═╕       │                        │
  13319.  │                          └───────┤;│──────┘                        │
  13320.  │                                  ╘═╛                                │
  13321.  │     ┌────┐        ╔══════════╗         ┌──┐         ╔═════════╗     │
  13322.  ├────│WITH├────┬──║expression╟───┬────│DO├────────║statement╟─────┤
  13323.  │     └────┘    │   ╚══════════╝   │     └──┘         ╚═════════╝     │
  13324.  │               │       ╒═╕        │                                  │
  13325.  │               └───────┤,│───────┘                                  │
  13326.  │                       ╘═╛                                           │
  13327.  │                 ┌─────┐                                             │
  13328.  ├─────────────┬──│BREAK├───┬────────────┬──────────────┬─────────────┤
  13329.  │             │   └─────┘   │            │              │             │
  13330.  │             │   ┌─────┐   │            │    ╔═════╗   │             │
  13331.  │             └──│CYCLE├───┘            └───║label╟───┘             │
  13332.  │                 └─────┘                     ╚═════╝                 │
  13333.  │                 ┌────┐                      ╔═════╗                 │
  13334.  ├────────────────│GOTO├─────────────────────║label╟─────────────────┤
  13335.  │                 └────┘                      ╚═════╝                 │
  13336.  │                              ┌──────┐                               │
  13337.  ├─────────────────────────────│RETURN├───────────────────────────────┤
  13338.  │                              └──────┘                               │
  13339.  │                       ╔════════════════════╗                        │
  13340.  ├──────────────────────║controlled statement╟────────────────────────┤
  13341.  │                       ╚════════════════════╝                        │
  13342.  └─────────────────────────────────────────────────────────────────────┘
  13343.  
  13344.  
  13345.  Controlled Statement
  13346.   │         ┌──┐        ╔══════════════════╗        ┌────┐              ┌
  13347.   ├────────│IF├───────║boolean expression╟───────│THEN├─────────┐    │
  13348.   │         └──┘        ╚══════════════════╝        └────┘         │    │
  13349.   │     ┌──────────────────────────────────────────────────────────┘    │
  13350.   │     │                     ┌───────────────────────────────────┐     │
  13351.   │     │   ╔═════════╗       │   ┌────┐           ╔═════════╗    │     │
  13352.   │     └──║statement╟───────┴──│ELSE├──────────║statement╟────┴─────┤
  13353.   │         ╚═════════╝           └────┘           ╚═════════╝          │
  13354.   │   ┌──────┐     ╔═════════╗      ┌─────┐      ╔══════════════════╗   │
  13355.   ├──│REPEAT├──┬─║statement╟──┬──│UNTIL├─────║boolean expression╟───┤
  13356.   │   └──────┘  │  ╚═════════╝  │   └─────┘      ╚══════════════════╝   │
  13357.   │             │      ╒═╕      │                                       │
  13358.   │             └──────┤;│─────┘                                       │
  13359.   │                    ╘═╛                                              │
  13360.   │    ┌─────┐     ╔══════════════════╗       ┌──┐      ╔═════════╗     │
  13361.   ├───│WHILE├────║boolean expression╟──────│DO├─────║statement╟─────┤
  13362.   │    └─────┘     ╚══════════════════╝       └──┘      ╚═════════╝     │
  13363.   │    ┌───┐              ╔══════════╗      ╒══╕     ╔══════════╗       │
  13364.   ├───│FOR├──┬────────┬─║identifier╟─────│:=├────║expression╟───┐   │
  13365.   │    └───┘  │  ┌───┐ │  ╚══════════╝      ╘══╛     ╚══════════╝   │   │
  13366.   │           └─│VAR├─┘                                            │   │
  13367.   │              └───┘                                              │   │
  13368.   │     ┌───────────────────────────────────────────────────────────┘   │
  13369.   │     │       ┌──┐                                                    │
  13370.   │     │  ┌───│TO├────┐                                               │
  13371.   │     │  │    └──┘    │                                               │
  13372.   │     │  │  ┌──────┐  │   ╔══════════╗        ┌──┐      ╔═════════╗   │
  13373.   │     └──┴─│DOWNTO├──┴──║expression╟───────│DO├─────║statement╟───┤
  13374.   │           └──────┘      ╚══════════╝        └──┘      ╚═════════╝   │
  13375.   │              ┌────┐           ╔══════════╗           ┌──┐           │
  13376.   └─────────────│CASE├──────────║expression╟──────────│OF├──────┐    │
  13377.                  └────┘           ╚══════════╝           └──┘      │    │
  13378.       ┌────────────────────────────────────────────────────────────┘    │
  13379.       │     ╔═════╗     ╒═╕      ╔═════════╗            ┌───┐           │
  13380.       └─┬──║cases╟────│:├─────║statement╟──┬──┬──┬──│END├───────────┘
  13381.         │   ╚═════╝     ╘═╛      ╚═════════╝  │  │  │   └───┘
  13382.         │                     ╒═╕             │  │  │
  13383.         └─────────────────────┤;│────────────┘  │  │
  13384.                               ╘═╛                │  │
  13385.       ┌──────────────────────────────────────────┘  └─────────────┐
  13386.       │      ┌─────────┐                 ╔═════════╗              │
  13387.       └─────│OTHERWISE├─────────────┬──║statement╟──┬───────────┘
  13388.              └─────────┘             │   ╚═════════╝  │
  13389.                                      │       ╒═╕      │
  13390.                                      └───────┤;│─────┘
  13391.                                              ╘═╛
  13392.  
  13393.  
  13394.  Boolean Expression
  13395.      ╔══════════╗
  13396.  ─┬─║expression╟───────────┬────────────────┬──────────────────────────
  13397.   │  ╚══════════╝           │                │
  13398.   │                       ┌──┐    ┌────┐   ┌─┐   ┌────┐
  13399.   │                       │AND├───│THEN│   │OR├──│ELSE│
  13400.   │                       └───┘    └─┬──┘   └──┘   └─┬──┘
  13401.   └──────────────────────────────────┴───────────────┘
  13402.  
  13403.  
  13404.  Expression
  13405.      ╔══════╗
  13406.  ─┬─║simple╟─────────┬─────┬──────┬─────┬──────┬─────┬──────┬──────────
  13407.   │  ╚══════╝         │     │      │     │      │     │      │
  13408.   │                  ╒╕   ╒═╕   ╒╕   ╒═╕   ╒╕   ╒═╕   ┌─┐
  13409.   │                  │<│   │<=│   │>│   │>=│   │=│   │<>│   │IN│
  13410.   │                  ╘╤╛   ╘╤═╛   ╘╤╛   ╘╤═╛   ╘╤╛   ╘╤═╛   └┬─┘
  13411.   └───────────────────┴─────┴──────┴─────┴──────┴─────┴──────┘
  13412.  
  13413.  
  13414.  Simple
  13415.                       ╔════╗
  13416.  ─────┬─────────┬──┬─║term╟───────┬─────┬─────┬──────┬─────────────────
  13417.       │   ╒═╕   │  │  ╚════╝       │     │     │      │
  13418.       ├──│+├───┤  │              ╒╕   ╒╕   ┌─┐  ┌──┐
  13419.       │   ╘═╛   │  │              │+│   │-│   │OR│  │XOR│
  13420.       │   ╒═╕   │  │              ╘╤╛   ╘╤╛   └┬─┘  └─┬─┘
  13421.       └──│-├───┘  │               │     │     │      │
  13422.           ╘═╛      └───────────────┴─────┴─────┴──────┘
  13423.  
  13424.  
  13425.  Term
  13426.          ╔══════╗
  13427.  ─────┬─║factor╟───┬────┬─────┬──────┬──────┬──────┬──────┬──────┬─────
  13428.       │  ╚══════╝   │    │     │      │      │      │      │      │
  13429.       │            ╒╕  ╒╕  ┌──┐  ┌──┐  ┌──┐  ┌──┐  ┌──┐  ┌──┐
  13430.       │            │*│  │/│  │DIV│  │MOD│  │ISR│  │SHL│  │SHR│  │AND│
  13431.       │            ╘╤╛  ╘╤╛  └─┬─┘  └─┬─┘  └─┬─┘  └─┬─┘  └─┬─┘  └─┬─┘
  13432.       └─────────────┴────┴─────┴──────┴──────┴──────┴──────┴──────┘
  13433.  
  13434.  
  13435.  Factor
  13436.   │      ╔══════════╗
  13437.   ├─────║identifier╟─────┬──────────────────────────────────────────┬──┬─
  13438.   │      ╚══════════╝     │    ╒═╕        ╔══════════╗         ╒═╕   │  │
  13439.   │                       └───│(├────┬──║expression╟───┬────│)├───┘  │
  13440.   │                            ╘═╛    │   ╚══════════╝   │     ╘═╛      │
  13441.   │                                   │       ╒═╕        │              │
  13442.   │                                   └───────┤,│───────┘              │
  13443.   │               ╒═╕        ╔══════════╗     ╘═╛ ╒═╕                   │
  13444.   ├──────────────│(├───────║expression╟────────│)├───────────────────┤
  13445.   │               ╘═╛        ╚══════════╝         ╘═╛                   │
  13446.   │                   ┌───┐              ╔══════╗                       │
  13447.   ├──────────────────│NOT├─────────────║factor╟───────────────────────┤
  13448.   │                   └───┘              ╚══════╝                       │
  13449.   │                ┌───┐                 ╔══════╗                       │
  13450.   ├───────────┬───│ADR├───┬────────────║factor╟───────────────────────┤
  13451.   │           │    └───┘   │             ╚══════╝                       │
  13452.   │           │    ┌───┐   │                                            │
  13453.   │           └───│ADS├───┘                                            │
  13454.   │                └───┘                                                │
  13455.   │      ┌────────────────────┐          ┌─────────────┐                │
  13456.   │      │    ╔══════════╗    │    ╒═╕   │   ╔═════╗   │    ╒═╕         │
  13457.   ├──────┴───║identifier╟────┴───│[├───┴──║cases╟───┴───│]├─────────┤
  13458.   │           ╚══════════╝         ╘═╛       ╚═════╝        ╘═╛         │
  13459.   │                            ╔════════╗                               │
  13460.   ├───────────────────────────║constant╟───────────────────────────────┤
  13461.   │                            ╚════════╝                               │
  13462.   │                            ╔════════╗                               │
  13463.   └───────────────────────────║variable╟───────────────────────────────┘
  13464.                                ╚════════╝
  13465.  
  13466.  
  13467.  Cases
  13468.                            ┌─────────────────────────────────┐
  13469.             ╔══════════╗   │   ╒══╕          ╔══════════╗    │
  13470.  ───────┬──║expression╟───┴──│..├─────────║expression╟────┴──────┬───
  13471.         │   ╚══════════╝       ╘══╛          ╚══════════╝           │
  13472.         │                            ╒═╕                            │
  13473.         └────────────────────────────┤,│───────────────────────────┘
  13474.                                      ╘═╛
  13475.  
  13476.  
  13477.  Real
  13478.                              ┌──────────────────────────────┐
  13479.                  ╔═════╗     │   ╒═╕          ╔═════╗       │
  13480.  ────────────┬──║digit╟───┬─┴──│.├──────┬──║digit╟───┬───┴───────────┐
  13481.              │   ╚═════╝   │     ╘═╛      │   ╚═════╝   │               │
  13482.              └─────────────┘              └─────────────┘               │
  13483.  ┌──────────────────────────────────────────────────────────────────────┘
  13484.  │    ┌───────────────────────────────────────────────────────────┐
  13485.  │    │   ╒═╕                                 ╔═════╗             │
  13486.  └────┼──│E├───┬──┬─────────┬────────────┬──║digit╟───┬─────────┴─────
  13487.       │   ╘═╛   │  │         │            │   ╚═════╝   │
  13488.       │   ╒═╕   │  │   ╒═╕   │            └─────────────┘
  13489.       ├──│e├───┤  ├──│+├───┤
  13490.       │   ╘═╛   │  │   ╘═╛   │
  13491.       │   ╒═╕   │  │   ╒═╕   │
  13492.       ├──│D├───┤  └──│-├───┘
  13493.       │   ╘═╛   │      ╘═╛
  13494.       │   ╒═╕   │
  13495.       └──│d├───┘
  13496.           ╘═╛
  13497.  
  13498.  
  13499.  Variable
  13500.       ╔══════════╗
  13501.  ────║identifier╟──┬──┬──────────────────────────────────────────┬──┬─
  13502.       ╚══════════╝  │  │    ╒═╕        ╔══════════╗         ╒═╕   │  │
  13503.                     │  ├───│[├────┬──║expression╟───┬────│]├───┤  │
  13504.                     │  │    ╘═╛    │   ╚══════════╝   │     ╘═╛   │  │
  13505.                     │  │           │       ╒═╕        │           │  │
  13506.                     │  │           └───────┤,│───────┘           │  │
  13507.                     │  │                   ╘═╛                    │  │
  13508.                     │  │        ╒═╕      ╔══════════╗             │  │
  13509.                     │  ├───────│.├─────║identifier╟─────────────┤  │
  13510.                     │  │        ╘═╛      ╚══════════╝             │  │
  13511.                     │  │                   ╒═╕                    │  │
  13512.                     │  └──────────────────│├────────────────────┘  │
  13513.                     │                      ╘═╛                       │
  13514.                     └────────────────────────────────────────────────┘
  13515.  
  13516.  
  13517.  Constant
  13518.                          ╔══════════╗                ╒═╕
  13519.  ──┬────────────────────║identifier╟───────────────│(├────────────┐   ┌
  13520.    │                     ╚══════════╝                ╘═╛            │   │
  13521.    │    ┌───────────────────────────────────────────────────────────┘   │
  13522.    │    │  ┌────────────────────────────────────┐                       │
  13523.    │    │  │  ┌──┐       ╔══════════╗     ┌──┐  │  ╔══════════╗    ╒═╕  │
  13524.    │    ├──┴─│DO├──────║expression╟────│OF├──┴─║expression╟─┬─│)├──┤
  13525.    │    │     └──┘       ╚══════════╝     └──┘     ╚══════════╝ │  ╘═╛  │
  13526.    │    │                            ╒═╕                        │       │
  13527.    │    └────────────────────────────┤,│───────────────────────┘       │
  13528.    │                                 ╘═╛                                │
  13529.    │             ╒═╕             ╔═════════╗            ╒═╕             │
  13530.    ├─────┬───┬──│,├────┬───┬───║character╟───┬───┬───│,├──┬───┬──────┤
  13531.    │     │   │   ╘═╛    │   │    ╚═════════╝   │   │    ╘═╛  │   │      │
  13532.    │     │   │          │   │    ╒═╕     ╒═╕   │   │         │   │      │
  13533.    │     │   │          │   └───│,├────│,├───┘   │         │   │      │
  13534.    │     │   │          │        ╘═╛     ╘═╛       │         │   │      │
  13535.    │     │   │          └──────────────────────────┘         │   │      │
  13536.    │     │   │                   ╔════════╗                  │   │      │
  13537.    │     │   └──────────────────║constant╟──────────────────┘   │      │
  13538.    │     │                       ╚════════╝                      │      │
  13539.    │     │                          ╒═╕                          │      │
  13540.    │     └──────────────────────────┤*│─────────────────────────┘      │
  13541.    │                                ╘═╛                                 │
  13542.    │                                ┌───┐                               │
  13543.    ├───────────────────────────────│NIL├───────────────────────────────┤
  13544.    │                                └───┘                               │
  13545.    │                              ╔══════╗                              │
  13546.    ├─────────────────────────────║number╟──────────────────────────────┤
  13547.    │                              ╚══════╝                              │
  13548.    │                               ╔════╗                               │
  13549.    └──────────────────────────────║real╟───────────────────────────────┘
  13550.                                    ╚════╝
  13551.  
  13552.  
  13553.  
  13554.  
  13555.  
  13556.  Appendix B  Microsoft Pascal Features and the ISO Standard
  13557.  
  13558.  ───────────────────────────────────────────────────────────────────────────
  13559.  
  13560.  B.1  Microsoft Pascal and the ISO Standard
  13561.  
  13562.  B.2  Summary of Microsoft Pascal Features
  13563.  
  13564.        B.2.1  Syntactic and Pragmatic Features
  13565.  
  13566.        B.2.2  Data types
  13567.  
  13568.        B.2.3  Operators and Intrinsics
  13569.  
  13570.        B.2.4  Control Flow and Structure Features
  13571.  
  13572.        B.2.5  Extend Level I/O and Files
  13573.  
  13574.        B.2.6  System Level I/O
  13575.  
  13576.  
  13577.  
  13578.  Microsoft Corporation fully supports the effort to standardize the
  13579.  Pascal language. A Microsoft representative sits on the ANSI/IEEE
  13580.  committee. At this writing, the ISO Pascal standard, Level 0 and
  13581.  Level 1, is still in draft status.
  13582.  
  13583.  MS-Pascal generally conforms to this current draft standard, but does
  13584.  not yet implement the proposed conformant array mechanism. This
  13585.  controversial method of passing arrays of different bounds as one
  13586.  parameter type has not been tested, and the details change from draft
  13587.  to draft. The conformant array scheme is not part of the ANSI/IEEE
  13588.  standard nor the ISO Level 0 standard.
  13589.  
  13590.  The super array type in MS-Pascal provides conformant array parameters,
  13591.  as well as dynamic length arrays allocated on the heap. Programs
  13592.  correctly written to the ISO standard (Level 0) or to the ANSI/IEEE
  13593.  standard should run correctly, without changes, under MS-Pascal.
  13594.  However, since MS-Pascal features introduce new reserved words and
  13595.  other elements, this goal cannot be fully realized.
  13596.  
  13597.  
  13598.  B.1  Microsoft Pascal and the ISO Standard
  13599.  
  13600.  
  13601.  The ISO standard defines a large number of error conditions, but
  13602.  allows a particular implementation to handle an error by documenting the
  13603.  fact that the error is not caught. These "errors not caught," and other
  13604.  differences between MS-Pascal and the ISO standard, are described below.
  13605.  An MS-Pascal program that conforms or tests conformance to the ISO standard
  13606.  must have both the metacommands $standard and $debug on.
  13607.  
  13608.  MS-Pascal allows the following minor extensions to the current
  13609.  ISO/ANSI/IEEE standard:
  13610.  
  13611.      1.  a question mark (?) as a substitute for the up arrow (^)
  13612.  
  13613.      2.  the underscore (_) in identifiers
  13614.  
  13615.  Due to the way the compiler binds identifiers, the new reserved words
  13616.  added at the extend and system levels cannot be used as identifiers at the
  13617.  standard level. A new directive, EXTERN, and new predeclared functions are
  13618.  standard in MS-Pascal.
  13619.  
  13620.  The current differences between Microsoft Pascal at the standard level and
  13621.  the current ISO/ANSI/IEEE standard are summarized in the following pages.
  13622.  
  13623.      1.  The ISO standard requires a separator between numbers and
  13624.          identifiers or keywords.
  13625.  
  13626.          In some cases, MS-Pascal doesn't require a separator between a
  13627.          number and an identifier or keyword, e.g., "100mod" is accepted as
  13628.          "100 mod" without error.
  13629.  
  13630.      2.  The ISO standard does not allow passing a component of a PACKED
  13631.          structure as a reference parameter.
  13632.  
  13633.          MS-Pascal specifically permits passing a CHAR element of a PACKED
  13634.          ARRAY [1 . . n] OF CHAR as a reference parameter. Passing a tag
  13635.          field as a reference is an error not caught. Passing other packed
  13636.          components gives the usual error.
  13637.  
  13638.      3.  The ISO standard does not include the textfile line-marker
  13639.          character in the set of CHAR values.
  13640.  
  13641.          MS-Pascal permits all 256 8-bit values as CHAR values; with some
  13642.          operating systems, a particular CHAR value (e.g., carriage return)
  13643.          is also the line marker character.
  13644.  
  13645.      4.  The ISO standard requires a variant to be given for all possible
  13646.          tag values.
  13647.  
  13648.          MS-Pascal permits a variant record declaration in which not all tag
  13649.          values are given.
  13650.  
  13651.      5.  The ISO standard requires that an identifier have only one meaning
  13652.          in any scope.
  13653.  
  13654.          In MS-Pascal, using an identifier and then redeclaring it in the
  13655.          same scope is an error not caught. For example, the following,
  13656.  
  13657.               CONST X = Y; VAR Y : CHAR;
  13658.  
  13659.          has two meanings for Y in the same scope. MS-Pascal generally uses
  13660.          the latest definition for an identifier. There is one ambiguous
  13661.          case: if you declare type FOO in one scope and in an inner scope
  13662.          TYPE P = ^ FOO; FOO = type; then FOO has two meanings and intent is
  13663.          ambiguous. In this case, the compiler uses the later definition of
  13664.          FOO and issues a warning.
  13665.  
  13666.      6.  The ISO standard requires field width "M" to be greater than zero
  13667.          in WRITE and WRITELN procedures.
  13668.  
  13669.          MS-Pascal treats M < 0 as if M = ABS (M), but field expansion takes
  13670.          place from the right rather than the left. M can also be zero, to
  13671.          WRITE nothing. Textfile READ (LN) and WRITE (LN) parameters can
  13672.          take both M and N parameters (ignored if not needed). The form
  13673.          "V::N" is allowed. When writing an INTEGER, the N parameter sets
  13674.          the output radix; when reading or writing an enumerated type, the N
  13675.          parameter sets the ordinal number or constant identifier option.
  13676.  
  13677.      7.  The ISO standard does not allow a variable created with the long
  13678.          form of NEW to be assigned, used in an expression, or passed as a
  13679.          parameter. However, this is difficult to check for at compile time
  13680.          and expensive to check at runtime.
  13681.  
  13682.          MS-Pascal allows assignments to these variables using the actual
  13683.          length of the target variable. The ISO standard error is not
  13684.          caught.
  13685.  
  13686.      8.  The ISO standard does not allow the short form of DISPOSE to be
  13687.          used on a structure allocated with the long form of NEW. The ISO
  13688.          standard only permits a variable allocated with the long form of
  13689.          NEW to be released with the long form of DISPOSE, and all tag
  13690.          fields should never change between the calls.
  13691.  
  13692.          MS-Pascal allows the short form of DISPOSE to be used on a
  13693.          structure allocated with the long form of NEW, and does not check
  13694.          for changes in tag values.
  13695.  
  13696.      9.  The ISO standard declares that when a "change of variant" occurs
  13697.          (such as when a new tag value is assigned), all the variant fields
  13698.          become undefined.
  13699.  
  13700.          MS-Pascal does not set the fields uninitialized when a new tag is
  13701.          assigned and so does not catch use of a variant field with an
  13702.          undefined value.
  13703.  
  13704.     10.  The ISO standard does not allow a variable with an active reference
  13705.          (i.e., the records of an executing WITH statement or an actual
  13706.          reference parameter) to be disposed (if a heap variable) or changed
  13707.          by a GET or PUT (if a file buffer variable).
  13708.  
  13709.          MS-Pascal does not catch these as errors.
  13710.  
  13711.     11.  The ISO standard currently defines I MOD J as an error if J < 0 and
  13712.          the result of MOD is positive, even if I is negative.
  13713.  
  13714.          MS-Pascal does not currently use the new draft standard semantics
  13715.          for the MOD operator. Programs intended to be portable should not
  13716.          use MOD unless both operands are positive.
  13717.  
  13718.     12.  The ISO standard at Level 1 defines conformant array.
  13719.  
  13720.          MS-Pascal does not implement the conformant array concept in Level
  13721.          1 of the ISO standard. Super arrays provide much the same
  13722.          functionality in a more flexible way.
  13723.  
  13724.     13.  The ISO standard requires the control variable of a FOR loop to be
  13725.          local to the immediate block. Any assignment to this control
  13726.          variable is an error.
  13727.  
  13728.          MS-Pascal allows a nonlocal variable to be used if it is STATIC, so
  13729.          either a local variable or one at the PROGRAM level can be a FOR
  13730.          statement control variable. MS-Pascal also does not detect an
  13731.          assignment to the control variable as an error if assignment occurs
  13732.          in a procedure or function called within the FOR statement.
  13733.  
  13734.     14.  The ISO standard requires the CHR argument to be INTEGER.
  13735.  
  13736.          MS-Pascal allows CHR to take any ordinal type.
  13737.  
  13738.  
  13739.  B.2  Summary of Microsoft Pascal Features
  13740.  
  13741.  
  13742.  This outline summarizes MS-Pascal extensions to the ISO standard.
  13743.  Unless otherwise noted, all are at the extend level.
  13744.  
  13745.  
  13746.  B.2.1  Syntactic and Pragmatic Features
  13747.  
  13748.  
  13749.      1.  The metalanguage (standard level)
  13750.  
  13751.               $brave                   $page
  13752.               $debug                   $pageif
  13753.               $decmath                 $pagesize
  13754.               $entry                   $pop
  13755.               $errors                  $push
  13756.               $extend                  $rangeck
  13757.               $floatcalls              $real
  13758.               $goto                    $rom
  13759.               $if $then $else $end     $runtime
  13760.               $include                 $simple
  13761.               $inconst                 $size
  13762.               $indexck                 $skip
  13763.               $initck                  $speed
  13764.               $integer                 $stackck
  13765.               $line                    $standard
  13766.               $linesize                $subtitle
  13767.               $list                    $symtab
  13768.               $mathck                  $system
  13769.               $message                 $tagck
  13770.               $nilck                   $title
  13771.               $ocode                   $warn
  13772.               $optbug
  13773.  
  13774.           2.  Extra listing (standard level)
  13775.  
  13776.               1.  flags for jumps, globals, identifier level, control level,
  13777.                   header, trailer
  13778.  
  13779.               2.  textual error and warning messages
  13780.  
  13781.           3.  Syntactic additions
  13782.  
  13783.               1.  ! as comment to end of line
  13784.  
  13785.               2.  square brackets equivalent to BEGIN/END
  13786.  
  13787.           4.  Nondecimal number notation
  13788.  
  13789.               1.  numeric constants with # or nn# (where
  13790.                    nn = 2..36)
  13791.  
  13792.               2.  DECODE/READ takes # notation
  13793.  
  13794.               3.  ENCODE/WRITE with N of 2, 8, 10, 16
  13795.  
  13796.           5.  Extended CASE range
  13797.  
  13798.               1.  for CASE statements and record variants
  13799.  
  13800.               2.  OTHERWISE for all other values
  13801.  
  13802.               3.  A..B for range of values
  13803.  
  13804.  
  13805.  B.2.2  Data Types and Modes
  13806.  
  13807.  
  13808.      1.  WORD type, WRD function, MAXWORD constant
  13809.  
  13810.      2.  REAL4 and REAL8 types
  13811.  
  13812.      3.  INTEGER4 type, MAXINT4 constant:
  13813.  
  13814.      4.  FLOAT4, ROUND4, and TRUNC4 functions
  13815.  
  13816.      5.  Address types (system level)
  13817.  
  13818.          1.  ADR and ADS types and operators
  13819.  
  13820.          2.  VARS and CONSTS parameters
  13821.  
  13822.      6.  SUPER array types
  13823.  
  13824.          1.  conformant parameters
  13825.  
  13826.          2.  dynamic length heap variables
  13827.  
  13828.          3.  multidimensional super arrays
  13829.  
  13830.          4.  STRING and LSTRING super types
  13831.  
  13832.      7.  LSTRING type, NULL constant, .LEN field
  13833.  
  13834.      8.  Explicit byte offsets in records (system level)
  13835.  
  13836.      9.  CONST and CONSTS reference parameters for constants and expressions
  13837.  
  13838.     10.  Structured (array, record, and set) constants
  13839.  
  13840.     11.  Extended functions returning any assignable type
  13841.  
  13842.     12.  Variable selection on values returned from functions
  13843.  
  13844.     13.  Attributes
  13845.  
  13846.          EXTERN          PORT
  13847.          EXTERNAL        PUBLIC
  13848.          FORTRAN         PURE
  13849.          INTERRUPT       READONLY
  13850.          ORIGIN          STATIC
  13851.  
  13852.  
  13853.  B.2.3  Operators and Intrinsics
  13854.  
  13855.  
  13856.      1.  Extend level operators:
  13857.  
  13858.          1.  shift operators: SHL SHR ISR
  13859.  
  13860.          2.  bitwise logical: AND  OR NOT XOR
  13861.  
  13862.          3.  set operators: < >
  13863.  
  13864.      2.  Constant expressions:
  13865.  
  13866.          1.  string constant concatenation with * operator
  13867.  
  13868.          2.  numeric, ordinal, Boolean expressions in type clauses
  13869.  
  13870.          3.  other constant functions:
  13871.  
  13872.              CHR         UPPER
  13873.              DIV         WRD
  13874.              HIBYTE      *
  13875.              HIWORD      +
  13876.              LOBYTE      -
  13877.              LOWER       <
  13878.              LOWORD      <=
  13879.              MOD         <>
  13880.              ORD         =
  13881.              RETYPE      >
  13882.              SIZEOF      >=
  13883.  
  13884.      3.  Additional intrinsic functions at extend level:
  13885.  
  13886.              ABORT         HIWORD
  13887.              BYLONG        LOBYTE
  13888.              BYWORD        LOWER
  13889.              DECODE        LOWORD
  13890.              ENCODE        RESULT
  13891.              EVAL          SIZEOF
  13892.              HIBYTE        UPPER
  13893.  
  13894.      4.  Additional intrinsic functions at system level:
  13895.  
  13896.              FILLC         MOVESL
  13897.              FILLSC        MOVESR
  13898.              MOVEL         RETYPE
  13899.              MOVER
  13900.  
  13901.      5.  Intrinsic functions that operate on strings:
  13902.  
  13903.          1.  for STRING or LSTRING: COPYSTR POSITN SCANEQ SCANNE
  13904.  
  13905.          2.  for LSTRING only: CONCAT INSERT DELETE COPYLST
  13906.  
  13907.      6.  MS-FORTRAN REAL library functions (standard level)
  13908.  
  13909.      7.  MS-Pascal library functions (standard level):
  13910.  
  13911.              ALLHQQ      MARKAS
  13912.              BEGOQQ      MEMAVL
  13913.              BEGXQQ      PLYUQQ
  13914.              DATE        PTYUQQ
  13915.              DISBIN      RELEAS
  13916.              ENDOQQ      SADDOK
  13917.              ENDXQQ      SMULOK
  13918.              ENABIN      TICS
  13919.              FREECT      TIME
  13920.              GTYUQQ      UADDOK
  13921.              LADDOK      UMULOK
  13922.              LMULOK      UNLOCK
  13923.              LOCKED      VECTIN
  13924.  
  13925.  
  13926.  B.2.4  Control Flow and Structure Features
  13927.  
  13928.  
  13929.  1.  Control flow statements: BREAK, CYCLE, and RETURN
  13930.  
  13931.  2.  Sequential control operators: AND THEN and OR ELSE in IF, WHILE,
  13932.      REPEAT
  13933.  
  13934.  3.  Extended FOR loop: FOR VAR variable
  13935.  
  13936.  4.  VALUE section to initialize static variables
  13937.  
  13938.  5.  Mixed order LABEL, CONST, TYPE, VAR, VALUE sections
  13939.  
  13940.  6.  Compilable MODULES, with global attributes
  13941.  
  13942.  7.  UNIT INTERFACE and IMPLEMENTATION:
  13943.  
  13944.      1.  interface version numbers, version checking
  13945.  
  13946.      2.  optional rename of constituents
  13947.  
  13948.      3.  guaranteed unique unit initialization
  13949.  
  13950.      4.  optional unit initialization
  13951.  
  13952.  
  13953.  B.2.5  Extend Level I/O and Files
  13954.  
  13955.  
  13956.      1.  Textfile line length declaration, TEXT (nnn)
  13957.  
  13958.      2.  READ enumerated, Boolean, pointer, STRING, LSTRING
  13959.  
  13960.      3.  WRITE enumerated, pointer, LSTRING
  13961.  
  13962.      4.  Negative M value to justify left instead of right
  13963.  
  13964.      5.  Temporary files
  13965.  
  13966.      6.  DIRECT mode files, SEEK procedure
  13967.  
  13968.      7.  ASSIGN, CLOSE, DISCARD, READSET, READFN procedures
  13969.  
  13970.      8.  FILEMODES type and constants, F.MODE access
  13971.  
  13972.      9.  Error trapping, F.TRAP and F.ERRS access
  13973.  
  13974.      10.  Enumerated I/O using identifier as string
  13975.  
  13976.  
  13977.  B.2.6  System level
  13978.  
  13979.  
  13980.  The MS-Pascal extension to the ISO standard offers full FCBFQQ type
  13981.  equivalent to FILE types.
  13982.  
  13983.  
  13984.  
  13985.  Appendix C  Microsoft Pascal and Other Pascals
  13986.  
  13987.  ───────────────────────────────────────────────────────────────────────────
  13988.  
  13989.  C.1  Implementations of Pascal
  13990.  
  13991.  C.2  Microsoft Pascal and UCSD Pascal
  13992.  
  13993.  
  13994.  
  13995.  At the standard level, Microsoft Pascal conforms to the current ISO
  13996.  draft standard. In theory, therefore, programs written in accordance with
  13997.  the ISO standard are portable and can be compiled with any MS-Pascal
  13998.  compiler with no problem.
  13999.  
  14000.  In practice, however, the majority of Pascal programs are written
  14001.  with at least some nonstandard features. In these cases, it is necessary to
  14002.  alter the Pascal source file to conform to the conventions used in
  14003.  Microsoft Pascal.
  14004.  
  14005.  
  14006.  C.1  Implementations of Pascal
  14007.  
  14008.  
  14009.  The areas in which different implementations of the Pascal language
  14010.  differ from one another fall into one of the following categories:
  14011.  
  14012.      1.  Interactive I/O
  14013.  
  14014.          MS-Pascal implements lazy evaluation to handle interactive I/O in a
  14015.          natural way. Other Pascals may implement this feature in different
  14016.          ways. For example, some systems require an initial READLN.
  14017.  
  14018.      2.  String handling
  14019.  
  14020.          MS-Pascal supports the super array type LSTRING to handle variable
  14021.          length strings efficiently. The ISO standard provides the PACK and
  14022.          UNPACK procedures for dealing with strings; other Pascals often
  14023.          have some improvement on the string handling facilities described
  14024.          in the standard.
  14025.  
  14026.      3.  Compiler controls
  14027.  
  14028.          Compiler controls implemented either as command line switches or as
  14029.          commands within source comments vary from Pascal to Pascal. To
  14030.          ensure portability, eliminate all embedded controls from comments.
  14031.  
  14032.      4.  Maximum set size
  14033.  
  14034.          The maximum set size varies from Pascal to Pascal. Some Pascals
  14035.          limit set size to 16 or 64 elements. In MS-Pascal, sets may
  14036.          contain up to 256 elements. This allows support of the SET OF
  14037.          CHAR.
  14038.  
  14039.      5.  Type compatibility
  14040.  
  14041.          The rules for type compatibility vary in their strictness. In some
  14042.          Pascals, structurally equivalent types with different names are
  14043.          compatible; in others (and in the ISO standard), they are not.
  14044.  
  14045.      6.  Out of block GOTOs
  14046.  
  14047.          Some Pascals do not permit the out-of-block GOTOs that are
  14048.          permitted in MS-Pascal.
  14049.  
  14050.      7.  Heap management
  14051.  
  14052.          Rather than use the procedures NEW and DISPOSE for managing dynamic
  14053.          allocation of memory, some Pascals use the MARK and RELEASE
  14054.          procedures. MS-Pascal supports both methods. (MARKAS and RELEAS
  14055.          are the MS-Pascal names for MARK and RELEASE.)
  14056.  
  14057.      8.  OTHERWISE in CASE statements and variant records
  14058.  
  14059.          If OTHERWISE is omitted in a CASE statement, control does not
  14060.          automatically pass to the next executable statement as in some
  14061.          other extended Pascals. Also, some other Pascals use the word ELSE
  14062.          or OTHERS instead of OTHERWISE.
  14063.  
  14064.      9.  Assigning filenames
  14065.  
  14066.          The ASSIGN procedure in MS-Pascal sets an operating system filename
  14067.          for a file. Some other Pascals use a second parameter to RESET and
  14068.          REWRITE for the filename.
  14069.  
  14070.     10.  Separate compilation
  14071.  
  14072.          Most Pascals exclude the EXTERN (or EXTERNAL) directive for
  14073.          procedures and functions. Many support the idea of a MODULE and/or
  14074.          an INTERFACE and IMPLEMENTATION, although the syntax may differ.
  14075.          Some do not support PUBLIC and EXTERN variables, but may use a
  14076.          FORTRAN COMMON approach. In the latter case, for portability, you
  14077.          should give all global variables in one MS-Pascal VAR section,
  14078.          using [PUBLIC] in the PROGRAM and [EXTERN] in the MODULE, and
  14079.          $include the same variable declarations in each.
  14080.  
  14081.     11.  Program parameters
  14082.  
  14083.          Some Pascals ignore program parameters. In some Pascals, all files
  14084.          must be program parameters.
  14085.  
  14086.     12.  Procedural parameters
  14087.  
  14088.          Several Pascals do not permit passing procedures and functions as
  14089.          parameters. Many do not permit passing any predeclared procedures
  14090.          or functions.
  14091.  
  14092.  
  14093.  C.2  Microsoft Pascal and UCSD Pascal
  14094.  
  14095.  
  14096.  Because UCSD Pascal(R) is one of the more prevalent Pascals for
  14097.  microcomputers, conversion of source files from UCSD to MS-Pascal, and vice
  14098.  versa, is likely to be a common occurrence. This section discusses the
  14099.  differences and similarities between the two Pascals.
  14100.  
  14101.  MS-Pascal has incorporated many of the UCSD extensions in one form or
  14102.  another. Table C.1 compares UCSD extensions with similar extensions
  14103.  available in MS-Pascal.
  14104.  
  14105.  
  14106.  Table C.1
  14107.  Microsoft Pascal and UCSD Pascal
  14108. ╓┌──────────────────────────────────┌────────────────────────────────────────╖
  14109.  UCSD Extension                     MS-Pascal Equivalent
  14110.  ───────────────────────────────────────────────────────────────────────────
  14111.  ATAN                               ARCTAN
  14112.  BLOCKREAD                          GETUQQ
  14113.  BLOCKWRITE                         PUTUQQ
  14114.  UCSD Extension                     MS-Pascal Equivalent
  14115. BLOCKWRITE                         PUTUQQ
  14116.  CLOSE                              CLOSE
  14117.  CLOSE (F, LOCK)                    CLOSE (F)
  14118.  CLOSE (F, PURGE)                   DISCARD (F)
  14119.  CONCAT                             CONCAT
  14120.  COPY                               COPYLST or MOVEL
  14121.  DELETE                             DELETE
  14122.  EXIT                               RETURN or GOTO
  14123.  FILLCHAR                           FILLC and FILLSC
  14124.  HALT                               ENDXQQ
  14125.  INSERT                             INSERT
  14126.  IORESULT, $I                       ERRS and TRAP fields
  14127.  LENGTH                             .LEN or STR [0]
  14128.  LOG                                LNDRQQ
  14129.  MARK                               MARKAS
  14130.  MEMAVAIL                           MEMAVL
  14131.  MOVELEFT                           MOVEL and MOVESL
  14132.  MOVERIGHT                          MOVER and MOVESR
  14133.  POS                                POSITN
  14134.  RELEASE                            RELEAS
  14135.  UCSD Extension                     MS-Pascal Equivalent
  14136. RELEASE                            RELEAS
  14137.  SCAN                               SCANEQ and SCANNE
  14138.  SEEK                               SEEK
  14139.  SIZEOF                             SIZEOF
  14140.  STR                                ENCODE
  14141.  STRING [n]                         LSTRING (n)
  14142.  UNIT                               UNIT
  14143.  Untyped Files                      FCBFQQ type
  14144.  
  14145.  The following notes describe comparative points of interest.
  14146.  
  14147.      1.  The UCSD STRING [n] type is logically similar to the MS-Pascal
  14148.          LSTRING (n) type. Both contain the length of a variable length
  14149.          string in element zero of an ARRAY of CHAR.
  14150.  
  14151.      2.  UCSD Pascal allocates pointer variables on the heap with MARK and
  14152.          RELEASE. Other Pascals normally use NEW and DISPOSE. MS-Pascal
  14153.          permits both methods of dynamic memory allocation.
  14154.  
  14155.      3.  MS-Pascal units are like UCSD Pascal units, with the following
  14156.          exceptions. In MS-Pascal, an INTERFACE must appear first in any
  14157.          compiland using it. Since UCSD Pascal has its own special file
  14158.          system, the name of the unit can be used to find the interface
  14159.          filename in a standard way.
  14160.  
  14161.          MS-Pascal requires a list of all identifiers exported from the unit
  14162.          in the UNIT clause itself and makes it optional in a USES clause.
  14163.          Different identifiers may be given in a USES clause to avoid
  14164.          identifier conflicts.
  14165.  
  14166.          Finally, MS-Pascal provides for unit initialization code and
  14167.          interface version control. Neither of these are available in UCSD
  14168.          Pascal.
  14169.  
  14170.      4.  CONCAT is a function in UCSD Pascal; in MS-Pascal, it is a
  14171.          procedure.
  14172.  
  14173.      5.  In UCSD Pascal, when a CASE statement whose control value does not
  14174.          select a statement is executed, the statement following the CASE
  14175.          statement is executed. In MS-Pascal, you must include an empty
  14176.          OTHERWISE clause to obtain this effect.
  14177.  
  14178.      6.  UCSD Pascal permits the use of the EOF (F) and EOLN (F) functions
  14179.          on a closed file; in MS-Pascal, this is an error.
  14180.  
  14181.      7.  UCSD Pascal permits comparison of records and arrays with the equal
  14182.          sign (=) and the not-equal sign (<>). In MS-Pascal, you must RETYPE
  14183.          the records and arrays to the same length STRING type, and then
  14184.          compare them as strings.
  14185.  
  14186.  
  14187.  
  14188.  Appendix D  ASCII Character Codes
  14189.  
  14190.  ───────────────────────────────────────────────────────────────────────────
  14191.  
  14192.  
  14193.  Table D.1
  14194.  ASCII Character Codes
  14195. ╓┌───────┌───────┌─────────────────┌───────┌───────┌─────────────────────────╖
  14196.  Dec     Hex     CHR               Dec     Hex     CHR
  14197.  ───────────────────────────────────────────────────────────────────────────
  14198.  Dec     Hex     CHR               Dec     Hex     CHR
  14199.  ───────────────────────────────────────────────────────────────────────────
  14200.  000     00H     NUL               064     40H     @
  14201.  001     01H     SOH               065     41H     A
  14202.  002     02H     STX               066     42H     B
  14203.  003     03H     ETX               067     43H     C
  14204.  004     04H     EOT               068     44H     D
  14205.  005     05H     ENQ               069     45H     E
  14206.  006     06H     ACK               070     46H     F
  14207.  007     07H     BEL               071     47H     G
  14208.  008     08H     BS                072     48H     H
  14209.  009     09H     HT                073     49H     I
  14210.  010     0AH     LF                074     4AH     J
  14211.  011     0BH     VT                075     4BH     K
  14212.  012     0CH     FF                076     4CH     L
  14213.  013     0DH     CR                077     4DH     M
  14214.  014     0EH     SO                078     4EH     N
  14215.  015     0FH     SI                079     4FH     O
  14216.  016     10H     DLE               080     50H     P
  14217.  017     11H     DC1               081     51H     Q
  14218.  018     12H     DC2               082     52H     R
  14219.  Dec     Hex     CHR               Dec     Hex     CHR
  14220. 018     12H     DC2               082     52H     R
  14221.  019     13H     DC3               083     53H     S
  14222.  020     14H     DC4               084     54H     T
  14223.  021     15H     NAK               085     55H     U
  14224.  022     16H     SYN               086     56H     V
  14225.  023     17H     ETB               087     57H     W
  14226.  024     18H     CAN               088     58H     X
  14227.  025     19H     EM                089     59H     Y
  14228.  026     1AH     SUB               090     5AH     Z
  14229.  027     1BH     ESCAPE            091     5BH     [
  14230.  028     1CH     FS                092     5CH     \
  14231.  029     1DH     GS                093     5DH     ]
  14232.  030     1EH     RS                094     5EH     ^
  14233.  031     1FH     US                095     5FH     ^
  14234.  032     20H     SPACE             096     60H     '
  14235.  033     21H     !                 097     61H     a
  14236.  034     22H     "                 098     62H     b
  14237.  035     23H     #                 099     63H     c
  14238.  036     24H     $                 100     64H     d
  14239.  037     25H     %                 101     65H     e
  14240.  Dec     Hex     CHR               Dec     Hex     CHR
  14241. 037     25H     %                 101     65H     e
  14242.  038     26H     &                 102     66H     f
  14243.  039     27H     '                 103     67H     g
  14244.  040     28H     (                 104     68H     h
  14245.  041     29H     )                 105     69H     i
  14246.  042     2AH     *                 106     6AH     j
  14247.  043     2BH     +                 107     6BH     k
  14248.  044     2CH     ,                 108     6CH     l
  14249.  045     2DH     -                 109     6DH     m
  14250.  046     2EH     .                 110     6EH     n
  14251.  047     2FH     /                 111     6FH     o
  14252.  048     30H     0                 112     70H     p
  14253.  049     31H     1                 113     71H     q
  14254.  050     32H     2                 114     72H     r
  14255.  051     33H     3                 115     73H     s
  14256.  052     34H     4                 116     74H     t
  14257.  053     35H     5                 117     75H     u
  14258.  054     36H     6                 118     76H     v
  14259.  055     37H     7                 119     77H     w
  14260.  056     38H     8                 120     78H     x
  14261.  Dec     Hex     CHR               Dec     Hex     CHR
  14262. 056     38H     8                 120     78H     x
  14263.  057     39H     9                 121     79H     y
  14264.  058     3AH     :                 122     7AH     z
  14265.  059     3BH     ;                 123     7BH     {
  14266.  060     3CH     <                 124     7CH     |
  14267.  061     3DH     =                 125     7DH     }
  14268.  062     3EH     >                 126     7EH     ~
  14269.  063     3FH     ?                 127     7FH     DEL
  14270.  
  14271.  
  14272.  Dec=decimal, Hex=hexadecimal (H), CHR=character,LF=Line Feed,
  14273.  FF=Form Feed, CR=Carriage Return, DEL=Rub out
  14274.  
  14275.  
  14276.  
  14277.  Appendix E  Summary of Microsoft Pascal Reserved Words
  14278.  
  14279.  ───────────────────────────────────────────────────────────────────────────
  14280.  
  14281.  Reserved words at the standard level:
  14282.  
  14283.       AND                 NIL
  14284.       ARRAY               NOT
  14285.       BEGIN               OF
  14286.       CASE                OR
  14287.       CONST               PACKED
  14288.       DIV                 PROCEDURE
  14289.       DO                  PROGRAM
  14290.       DOWNTO              RECORD
  14291.       ELSE                REPEAT
  14292.       END                 SET
  14293.       FILE                THEN
  14294.       FOR                 TO
  14295.       FUNCTION            TYPE
  14296.       GOTO                UNTIL
  14297.       IF                  VAR
  14298.       IN                  WHILE
  14299.       LABEL               WITH
  14300.       MOD
  14301.  
  14302.  Additional reserved words at the extend level:
  14303.  
  14304.       BREAK               RETURN
  14305.       CONSTS              SHL
  14306.       CYCLE               SHR
  14307.       IMPLEMENTATION      UNIT
  14308.       INTERFACE           USES
  14309.       ISR                 VALUE
  14310.       MODULE              VARS
  14311.       OTHERWISE           XOR
  14312.  
  14313.  Additional reserved words at the system level:
  14314.  
  14315.       ADR
  14316.       ADS
  14317.  
  14318.  Names of attributes:
  14319.  
  14320.       EXTERN              PORT
  14321.       EXTERNAL            PUBLIC
  14322.       FORTRAN             PURE
  14323.       INTERRUPT           READONLY
  14324.       ORIGIN              STATIC
  14325.  
  14326.  Names of directives:
  14327.  
  14328.       EXTERN
  14329.       EXTERNAL
  14330.       FORWARD
  14331.  
  14332.  Logically, directives are reserved words. Since additional directives
  14333.  are allowed in ISO Pascal, all are included at the standard level. Note
  14334.  that EXTERN is both a directive and an attribute; EXTERNAL is a synonym for
  14335.  EXTERN in both cases. This provides compatibility with a number of other
  14336.  Pascals.
  14337.  
  14338.  
  14339.  
  14340.  Appendix F  Summary of Available Procedures and Functions
  14341.  
  14342.  ───────────────────────────────────────────────────────────────────────────
  14343.  
  14344.  This appendix provides a summary listing of all available functions and
  14345.  procedures, along with the name of the group in which they are presented in
  14346.  Section 15.1, "Categories of Available Procedures and Functions."
  14347.  
  14348.  
  14349.  Table F.1
  14350.  Procedures and Functions
  14351. ╓┌────────┌──────────────────────────────┌───────────────────────────────────╖
  14352.  Name     Description                    Category
  14353.  ───────────────────────────────────────────────────────────────────────────
  14354.  ABORT    Terminate program              Extend level
  14355.  ABS      Absolute value function        Arithmetic
  14356.  ACDRQQ   REAL8 arc cosine function      Arithmetic
  14357.  ACSRQQ   REAL4 arc cosine function      Arithmetic
  14358.  AIDRQQ   REAL8 truncate function        Arithmetic
  14359.  AISRQQ   REAL4 truncate function        Arithmetic
  14360.  ALLHQQ   Allocate heap item             Library
  14361.  ALLMQQ   Segmented heap management      Library
  14362.  ANDRQQ   REAL8 round toward zero        Arithmetic
  14363.  ANSRQQ   REAL4 round toward zero        Arithmetic
  14364.  ARCTAN   Arc tangent function           Arithmetic
  14365.  ASDRQQ   REAL8 arc sine function        Arithmetic
  14366.  Name     Description                    Category
  14367. ASDRQQ   REAL8 arc sine function        Arithmetic
  14368.  ASSRQQ   REAL4 arc sine function        Arithmetic
  14369.  ASSIGN   Assign filename                File system
  14370.  ATDRQQ   REAL8 arc tangent function     Arithmetic
  14371.  ATSRQQ   REAL4 arc tangent function     Arithmetic
  14372.  A2DRQQ   REAL8 arc tangent (A/B)        Arithmetic
  14373.  A2SRQQ   REAL4 arc tangent (A/B)        Arithmetic
  14374.  BEGOQQ   Initialize user                Library
  14375.  BEGXQQ   Overall initialization         Library
  14376.  BYLONG   WORD or INTEGER to INTEGER4    Extend level
  14377.  BYWORD   Put bytes in word              Extend level
  14378.  CHDRQQ   REAL8 hyperbolic cosine        Arithmetic
  14379.  CHR      Get ASCII char of value        Data conversion
  14380.  CHSRQQ   REAL4 hyperbolic cosine        Arithmetic
  14381.  CLOSE    Close file                     File system
  14382.  CNDRQQ   REAL8 cosine function          Arithmetic
  14383.  CNSRQQ   REAL4 cosine function          Arithmetic
  14384.  CONCAT   Concatenate LSTRING            String
  14385.  COPYLST  Copy to LSTRING                String
  14386.  COPYSTR  Copy to STRING                 String
  14387.  Name     Description                    Category
  14388. COPYSTR  Copy to STRING                 String
  14389.  COS      Cosine function                Arithmetic
  14390.  DATE     Date function                  Library
  14391.  DECODE   Decode LSTRING to variable     Extend level
  14392.  DELETE   Remove portion of LSTRING      String
  14393.  DISBIN   Disable interrupts             Library
  14394.  DISCARD  Close and delete file          File system
  14395.  DISMQQ   Segmented heap management      Library
  14396.  DISPOSE  Dispose of heap item           Dynamic alloc'n
  14397.  ENABIN   Enable interrupts              Library
  14398.  ENCODE   Encode expression to LSTRING   Extend level
  14399.  ENDOQQ   User termination               Library
  14400.  ENDXQQ   Program termination            Library
  14401.  EOF      Boolean end-of-file            File system
  14402.  EOLN     Boolean end-of-line            File system
  14403.  EVAL     Evaluate functions             Extend level
  14404.  EXDRQQ   REAL8 exponential function     Arithmetic
  14405.  EXP      Exponential function           Arithmetic
  14406.  EXSRQQ   REAL4 exponential function     Arithmetic
  14407.  FILLC    Fill area with C, relative     System level
  14408.  Name     Description                    Category
  14409. FILLC    Fill area with C, relative     System level
  14410.  FILLSC   Fill area with C, segmented    System level
  14411.  FLOAT    Convert INTEGER to REAL        Data conversion
  14412.  FLOAT4   Convert INTEGER4 to REAL       Data conversion
  14413.  FREECT   Give count of free blocks      Library
  14414.  FREMQQ   Segmented heap management      Library
  14415.  GET      Get next file component        File system
  14416.  GETMQQ   Segmented heap management      Library
  14417.  GTYUQQ   Direct terminal input          Library
  14418.  HDLUQQ   Returns MS-DOS 2.0 file
  14419.           handle for a Pascal file       File system
  14420.  HIBYTE   Get high BYTE                  Extend level
  14421.  HIWORD   Get high WORD                  Extend level
  14422.  INSERT   Insert string                  String
  14423.  LADDOK   32-bit signed addition check   Library
  14424.  LDDRQQ   REAL8 log base ten function    Arithmetic
  14425.  LDSRQQ   REAL4 log base ten function    Arithmetic
  14426.  LMULOK   32-bit signed multiply check   Library
  14427.  LN       Natural log function           Arithmetic
  14428.  LNDRQQ   REAL8 natural log              Arithmetic
  14429.  Name     Description                    Category
  14430. LNDRQQ   REAL8 natural log              Arithmetic
  14431.  LNSRQQ   REAL4 natural log              Arithmetic
  14432.  LOBYTE   Get low BYTE                   Extend level
  14433.  LOCKED   Resource locked status         Library
  14434.  LOWER    Get lower bound                Extend level
  14435.  LOWORD   Get low WORD                   Extend level
  14436.  MARKAS   Mark heap bounds               Library
  14437.  MEMAVL   Available memory               Library
  14438.  MDDRQQ   REAL8 modulo function          Arithmetic
  14439.  MDSRQQ   REAL4 modulo function          Arithmetic
  14440.  MNDRQQ   REAL8 minimum function         Arithmetic
  14441.  MNSRQQ   REAL4 minimum function         Arithmetic
  14442.  MOVEL    Move bytes left, relative      System level
  14443.  MOVER    Move bytes right, relative     System level
  14444.  MOVESL   Move bytes left, segmented     System level
  14445.  MOVESR   Move bytes right, segmented    System level
  14446.  MXDRQQ   REAL8 maximum function         Arithmetic
  14447.  MXSRQQ   REAL4 maximum function         Arithmetic
  14448.  NEW      Allocate new heap item         Library
  14449.  ODD      Boolean odd function           Data conversion
  14450.  Name     Description                    Category
  14451. ODD      Boolean odd function           Data conversion
  14452.  ORD      Get ordinal value              Data conversion
  14453.  PACK     Pack CHAR array                Data conversion
  14454.  PAGE     Write new page                 File system
  14455.  PIDRQQ   REAL8 to INTEGER power         Arithmetic
  14456.  PISRQQ   REAL4 to INTEGER power         Arithmetic
  14457.  PLYUQQ   Direct terminal end line       Library
  14458.  POSITN   Find position of substring     String
  14459.  PRED     Predecessor function           Data conversion
  14460.  PRDRQQ   REAL8 to REAL8 power           Arithmetic
  14461.  PRSRQQ   REAL4 to REAL4 power           Arithmetic
  14462.  PTYUQQ   Direct terminal output         Library
  14463.  PUT      Put value to file              File system
  14464.  READ     Read file                      File system
  14465.  READFN   Read filename                  File system
  14466.  READLN   Read file to end of line       File system
  14467.  READSET  Read set                       File system
  14468.  RELEAS   Release heap space             Library
  14469.  RESET    Ready file for read            File system
  14470.  RESULT   Return result of function      Extend level
  14471.  Name     Description                    Category
  14472. RESULT   Return result of function      Extend level
  14473.  RETYPE   Force expression to type       System level
  14474.  REWRITE  Ready file for write           File system
  14475.  ROUND    Round REAL to INTEGER          Data conversion
  14476.  ROUND4   Round REAL to INTEGER4         Data conversion
  14477.  SADDOK   16-bit signed addition check   Library
  14478.  SCANEQ   Scan until char found          String
  14479.  SCANNE   Scan until char not found      String
  14480.  SEEK     Position at direct file record File system
  14481.  SHDRQQ   REAL8 hyperbolic sine          Arithmetic
  14482.  SHSRQQ   REAL4 hyperbolic sine          Arithmetic
  14483.  SIN      Sine function                  Arithmetic
  14484.  SIZEOF   Get size of structure          Extend level
  14485.  SMULOK   16-bit signed multiply check   Library
  14486.  SNDRQQ   REAL8 sine function            Arithmetic
  14487.  SNSRQQ   REAL4 sine function            Arithmetic
  14488.  SQR      Square function                Arithmetic
  14489.  SQRT     Square root function           Arithmetic
  14490.  SRDRQQ   REAL8 square root              Arithmetic
  14491.  SRSRQQ   REAL4 square root              Arithmetic
  14492.  Name     Description                    Category
  14493. SRSRQQ   REAL4 square root              Arithmetic
  14494.  SUCC     Successor function             Data conversion
  14495.  THDRQQ   REAL8 hyperbolic tangent       Arithmetic
  14496.  THSRQQ   REAL4 hyperbolic tangent       Arithmetic
  14497.  TICS     Time in arbitrary units        Library
  14498.  TIME     Time of day function           Library
  14499.  TNDRQQ   REAL8 tangent function         Arithmetic
  14500.  TNSRQQ   REAL4 tangent function         Arithmetic
  14501.  TRUNC    Truncate REAL to INTEGER       Data conversion
  14502.  TRUNC4   Truncate REAL to INTEGER4      Data conversion
  14503.  UADDOK   Unsigned addition check        Library
  14504.  UMULOK   Unsigned multiply check        Library
  14505.  UNLOCK   Unlock resource                Library
  14506.  UNPACK   Unpack STRING to array         Data conversion
  14507.  UPPER    Get upper bound                Extend level
  14508.  VECTIN   Set interrupt vector           Library
  14509.  WRD      Convert to WORD value          Data conversion
  14510.  WRITE    Write file                     File system
  14511.  WRITELN  Write line to file             File system
  14512.  
  14513.  
  14514.  
  14515.  Appendix G  Summary of Microsoft Pascal Metacommands
  14516.  
  14517.  ───────────────────────────────────────────────────────────────────────────
  14518.  
  14519.  This appendix provides a single alphabetical list of all of the
  14520.  metacommands described in Chapter 18, "Microsoft Pascal Metacommands."
  14521.  Defaults, if any, are shown following the metacommand.
  14522.  
  14523.  
  14524.  Table G.1
  14525.  Microsoft Pascal Metacommands
  14526. ╓┌────────────────────┌──────────────────────────────────────────────────────╖
  14527.  Metacommand          Action
  14528.  ───────────────────────────────────────────────────────────────────────────
  14529.  $brave+              Sends messages to the terminal screen
  14530.  
  14531.  $debug-              Turns on or off all error checking (CK)
  14532.  
  14533.  $decmath-            Directs the compiler to carry out
  14534.  Metacommand          Action
  14535. $decmath-            Directs the compiler to carry out
  14536.                       floating-point operations using the
  14537.                       decimal support routines in DECMATH.LIB
  14538.  
  14539.  $entry-              Generates procedure entry and exit
  14540.                       calls for debugger
  14541.  
  14542.  $errors:25           Sets number of errors allowed per page
  14543.  
  14544.  $extend              Adds extend level features
  14545.  
  14546.  $floatcalls+         Directs the compiler to generate calls
  14547.                       to real number floating-point routines
  14548.  
  14549.  $goto-               Flags GOTOs as "considered harmful"
  14550.  
  14551.  $if constant         Allows conditional compilation of
  14552.    $then text1        text1 source if constant is greater than
  14553.    $else text2        zero
  14554.  $end
  14555.  Metacommand          Action
  14556. $end
  14557.  
  14558.  $include:'file'      Switches compilation to file named
  14559.  
  14560.  $inconst             Allows interactive setting of constant
  14561.                       values at compile time
  14562.  
  14563.  $indexck-            Checks for array index values in range
  14564.  
  14565.  $initck-             Checks for use of uninitialized values
  14566.  
  14567.  $integer             Sets the length of the integer type
  14568.  
  14569.  $line-               Generates line number calls for debugger
  14570.  
  14571.  $linesize:79         Sets width of source listing
  14572.  
  14573.  $list+               Turns on or off source listing
  14574.  
  14575.  $mathck-             Checks for mathematical errors
  14576.  Metacommand          Action
  14577. $mathck-             Checks for mathematical errors
  14578.  
  14579.  $message             Displays a message on terminal screen
  14580.  
  14581.  $nilck-              Checks for bad pointer values
  14582.  
  14583.  $ocode+              Turns on or off object code listing
  14584.  
  14585.  $page+               Skips to next page
  14586.  
  14587.  $page:n              Sets page number for next page
  14588.  
  14589.  $pageif:n            Skips to next page if less than
  14590.                       n lines left
  14591.  
  14592.  $pagesize:55         Sets page length of source listing
  14593.  
  14594.  $pop                 Restores saved value of all metacommands
  14595.  
  14596.  $push                Saves current value of all metacommands
  14597.  Metacommand          Action
  14598. $push                Saves current value of all metacommands
  14599.  
  14600.  $rangeck-            Checks for subrange validity
  14601.  
  14602.  $real                Sets the length of the REAL type
  14603.  
  14604.  $rom                 Warns on static initialization
  14605.  
  14606.  $runtime-            Determines context of runtime errors
  14607.  
  14608.  $simple              Disables global optimizations
  14609.  
  14610.  $size                Minimizes size of code generated
  14611.  
  14612.  $skip:n              Skips n lines or to end of page
  14613.  
  14614.  $speed               Minimizes execution time of code
  14615.  
  14616.  $stackck-            Checks for stack overflow at entry
  14617.  
  14618.  Metacommand          Action
  14619. 
  14620.  $standard            Enables standard level only
  14621.  
  14622.  $subtitle:'subt'     Sets page subtitle
  14623.  
  14624.  $symtab+             Sends symbol table to source listing
  14625.  
  14626.  $system              Adds extend and system level features
  14627.  
  14628.  $tagck-              Checks tag fields in variant records
  14629.  
  14630.  $title:'title'       Gives page title for source listing
  14631.  
  14632.  $warn+               Gives warning messages in source listing
  14633.  
  14634.  
  14635.  
  14636.  
  14637.  
  14638.  Index
  14639.  
  14640.  
  14641.  Symbol
  14642.  ──────────────────────────────────────────────────────────────────────────
  14643.  (>) operator
  14644.  (>=) operator
  14645.  (<>) operator
  14646.  (>=) operator
  14647.  ([ and ]) square brackets
  14648.  (:=) assignment
  14649.  (!) comment to end-of-line
  14650.  (*) operator
  14651.  (*) operator
  14652.  (*) operator
  14653.  (+) operator
  14654.  (+) operator
  14655.  (-) operator
  14656.  (-) operator
  14657.  (/) operator
  14658.  (<=) operator
  14659.  (<=) operator
  14660.  (=) operator
  14661.  (=) operator
  14662.  (<) operator
  14663.  (<) operator
  14664.  (<) operator
  14665.  (.) period
  14666.  (?) question mark
  14667.  (#) radix separator
  14668.  (_) underscore
  14669.  
  14670.  
  14671.  A
  14672.  ──────────────────────────────────────────────────────────────────────────
  14673.  A2DRQQ function
  14674.  A2SRQQ function
  14675.  ABORT
  14676.  ABORT procedure
  14677.  ABS function
  14678.  ACDRQQ function
  14679.  ACSRQQ function
  14680.  Actual parameters
  14681.  Address Types
  14682.  ADR operator
  14683.  ADRMEM predeclared type
  14684.  ADS operator
  14685.  ADSMEM predeclared type
  14686.  AIDRQQ function
  14687.  AISRQQ function
  14688.  Aliases
  14689.  ALLHQQ function
  14690.  ALLMQQ
  14691.  AND operator
  14692.  AND THEN operator
  14693.  ANDRQQ function
  14694.  ANSRQQ function
  14695.  Appendix A
  14696.  ARCTAN function
  14697.  Arithmetic functions
  14698.  Arrays
  14699.  Arrays
  14700.      component type
  14701.      conformant
  14702.      dynamic
  14703.      index type
  14704.      n-dimensional
  14705.      super
  14706.  ASCII character codes
  14707.  ASCII character set
  14708.  ASCII files
  14709.  ASDRQQ function
  14710.  ASSIGN procedure
  14711.  Assignment compatibility
  14712.  Assignment statement
  14713.  ASSRQQ function
  14714.  ATDRQQ function
  14715.  ATSRQQ function
  14716.  Attributes
  14717.  Attributes
  14718.      EXTERN
  14719.      EXTERNAL
  14720.      for functions
  14721.      for procedures
  14722.      for variables
  14723.      FORTRAN
  14724.      INTERRUPT
  14725.      ORIGIN
  14726.      PORT
  14727.      PUBLIC
  14728.      PURE
  14729.      READONLY
  14730.      STATIC
  14731.  Available procedures and functions
  14732.      summary of
  14733.  
  14734.  
  14735.  B
  14736.  ──────────────────────────────────────────────────────────────────────────
  14737.  Base type
  14738.  BEGIN
  14739.  BEGOQQ procedure
  14740.  BEGXQQ procedure
  14741.  BINARY files
  14742.  boolean expression
  14743.  BOOLEAN expressions
  14744.  Boolean operator
  14745.  BOOLEAN type
  14746.  BRAVE metacommand
  14747.  BREAK statement
  14748.  Buffer variable
  14749.  BYLONG function
  14750.  BYTE predeclared subrange
  14751.  BYWORD function
  14752.  
  14753.  
  14754.  C
  14755.  ──────────────────────────────────────────────────────────────────────────
  14756.  CASE
  14757.      constant list
  14758.      constant
  14759.      constant
  14760.      index
  14761.      statement
  14762.  CHAR type
  14763.  Character strings
  14764.  CHDRQQ function
  14765.  CHR function
  14766.  CHSRQQ function
  14767.  CLOSE procedure
  14768.  CLOSE procedure
  14769.  CNDRQQ function
  14770.  CNSRQQ function
  14771.  Comments
  14772.  Compatibility
  14773.      assignment
  14774.      of types
  14775.  Compilable parts of programs
  14776.  Compilands
  14777.  Compiling programs
  14778.  Component type
  14779.  Component variable
  14780.  Compound statements
  14781.  CONCAT procedure
  14782.  Concurrent I/O
  14783.  Conditional compilation
  14784.  Conditional statement
  14785.  Conformant array
  14786.  CONST
  14787.  Constant parameters
  14788.  Constants
  14789.  Constants
  14790.      declarations
  14791.      enumerated
  14792.      expressions
  14793.      identifiers
  14794.      identifiers
  14795.      length restriction
  14796.      string
  14797.      structured
  14798.      structured
  14799.          array
  14800.          record
  14801.          set
  14802.  CONSTS parameters
  14803.  CONSTS
  14804.  Control flow
  14805.  Control variable
  14806.  COPYLST procedure
  14807.  COPYSTR procedure
  14808.  COS function
  14809.  CYCLE statement
  14810.  
  14811.  
  14812.  D
  14813.  ──────────────────────────────────────────────────────────────────────────
  14814.  DATE procedure
  14815.  DEBUG metacommand
  14816.  Debugging metacommands
  14817.  Declarations
  14818.      flexible order of
  14819.      FORWARD
  14820.      function
  14821.      identifiers
  14822.      procedure
  14823.      type
  14824.      variables
  14825.  DECMATH metacommand
  14826.  DECODE function
  14827.  DELETE procedure
  14828.  Digits
  14829.  DIRECT files
  14830.  DIRECT
  14831.  Directives
  14832.      EXTERN
  14833.      EXTERNAL
  14834.      for functions
  14835.      for procedures
  14836.      FORWARD
  14837.  DISBIN procedure
  14838.  DISCARD procedure
  14839.  DISMQQ procedure
  14840.  DISPOSE procedure
  14841.  DIV operator
  14842.  DO (in structured constants)
  14843.  Dynamic array
  14844.  
  14845.  
  14846.  E
  14847.  ──────────────────────────────────────────────────────────────────────────
  14848.  Empty statement
  14849.  Empty variant
  14850.  EMSEQQ
  14851.  ENABIN procedure
  14852.  ENCODE function
  14853.  END
  14854.  ENDOQQ procedure
  14855.  ENDXQQ procedure
  14856.  ENTGQQ
  14857.  Entire variable
  14858.  ENTRY metacommand
  14859.  Enumerated
  14860.      constants
  14861.      I/O
  14862.      types
  14863.  EOF function
  14864.  EOLN function
  14865.  ERRORS metacommand
  14866.  EVAL procedure
  14867.  EXDRQQ function
  14868.  EXP function
  14869.  Explicit field offsets
  14870.  Expressions
  14871.      constant
  14872.      simple
  14873.  EXSRQQ function
  14874.  Extend level
  14875.      CASE constant
  14876.      FOR-LOOP
  14877.      function
  14878.      intrinsics
  14879.      I/O
  14880.      Pascal
  14881.  EXTEND metacommand
  14882.  EXTERN attribute
  14883.  EXTERN directive
  14884.  EXTERNAL attribute
  14885.  EXTERNAL directive
  14886.  
  14887.  
  14888.  F
  14889.  ──────────────────────────────────────────────────────────────────────────
  14890.  FCBFQQ
  14891.  Features of MS-Pascal
  14892.  Features
  14893.      constant expressions
  14894.      structured constants
  14895.      VALUE section
  14896.  Fields
  14897.      identifiers
  14898.      variables
  14899.  Files
  14900.      buffer variable
  14901.      FCB fields
  14902.          ERRS
  14903.          MODE
  14904.          TRAP
  14905.      FCBFQQ
  14906.      INPUT
  14907.      modes
  14908.          DIRECT
  14909.          SEQUENTIAL
  14910.          TERMINAL
  14911.      OUTPUT
  14912.      structures
  14913.          ASCII
  14914.          BINARY
  14915.      temporary
  14916.  FILLC procedure
  14917.  FILLSC procedure
  14918.  Flexible order of declarations
  14919.  FLOAT function
  14920.  FLOAT4 function
  14921.  FLOATCALLS metacommand
  14922.  FOR statement
  14923.  FOR VAR feature
  14924.  formal parameters
  14925.  Formatting parameters
  14926.  Formatting rules
  14927.  FORTRAN attribute
  14928.  FORTRAN library
  14929.  FORWARD directive
  14930.  Forward pointer
  14931.  FREECT function
  14932.  FREMQQ function
  14933.  Function block
  14934.  Function designators
  14935.  Function parameters
  14936.  Functional parameter
  14937.  Functional types
  14938.  Functions
  14939.      A2DRQQ
  14940.      A2SRQQ
  14941.      ABS
  14942.      ACDRQQ
  14943.      ACSRQQ
  14944.      AIDRQQ
  14945.      AISRQQ
  14946.      ALLHQQ
  14947.      ALLMQQ
  14948.      ANDRQQ
  14949.      ANSRQQ
  14950.      ARCTAN
  14951.      arithmetic
  14952.      ASDRQQ
  14953.      ASSRQQ
  14954.      available
  14955.          summary of
  14956.      BYLONG
  14957.      BYWORD
  14958.      CHDRQQ
  14959.      CHR
  14960.      CHSRQQ
  14961.      COS
  14962.      declarations
  14963.      DECODE
  14964.      designators
  14965.      ENCODE
  14966.      EOF
  14967.      EOLN
  14968.      EXP
  14969.  FUnctions
  14970.      FLOAT
  14971.  Functions
  14972.      FLOAT4
  14973.      FREECT
  14974.      FREMQQ
  14975.      GETMQQ
  14976.      GETYQQ
  14977.      heading
  14978.      HIBYTE
  14979.      HIWORD
  14980.      identifiers
  14981.      LADDOK
  14982.      LDDRQQ
  14983.      LDSRQQ
  14984.      LMULOK
  14985.      LN
  14986.  FUNCTIONS
  14987.      LOBYTE
  14988.  Functions
  14989.      LOCKED
  14990.      LOWER
  14991.      LOWORD
  14992.      MARKAS
  14993.      MDDRQQ
  14994.      MDSRQQ
  14995.      MEMAVL
  14996.      MNDRQQ
  14997.      MNSRQQ
  14998.      MXDRQQ
  14999.      MXSRQQ
  15000.      ODD
  15001.      ORD
  15002.      PIDRQQ
  15003.      PISRQQ
  15004.      POSITN
  15005.      RESULT
  15006.      RETYPE
  15007.      ROUND
  15008.      ROUND4
  15009.      SADDOK
  15010.      SCANEQ
  15011.      SCANNE
  15012.      SHDRQQ
  15013.      SHSRQQ
  15014.      SIN
  15015.      SIZEOF
  15016.      SQR
  15017.      SQRT
  15018.      SUCC
  15019.      THDRQQ
  15020.      THSRQQ
  15021.      TIC
  15022.      TNDRQQ
  15023.      TNSRQQ
  15024.      TRUNC
  15025.      TRUNC4
  15026.  FUnctions
  15027.      UADDOK
  15028.  Functions
  15029.      UMULOK
  15030.      WRD
  15031.  
  15032.  
  15033.  G
  15034.  ──────────────────────────────────────────────────────────────────────────
  15035.  GET procedure
  15036.  GETMQQ function
  15037.  GOTO metacommand
  15038.  GOTO statement
  15039.  GTYUQQ function
  15040.  
  15041.  
  15042.  H
  15043.  ──────────────────────────────────────────────────────────────────────────
  15044.  Headings
  15045.      function
  15046.      procedure
  15047.  HIBYTE function
  15048.  HIWORD function
  15049.  
  15050.  
  15051.  I
  15052.  ──────────────────────────────────────────────────────────────────────────
  15053.  Identifiers
  15054.      components
  15055.      declarations
  15056.      definition of
  15057.      predeclared
  15058.      program
  15059.      record field
  15060.      restrictions
  15061.      scope of
  15062.      type
  15063.      underscore
  15064.  IF metacommand
  15065.  IF statement
  15066.  Implementations of Pascal
  15067.  IN operator
  15068.  INCLUDE metacommand
  15069.  INCONST metacommand
  15070.  INDEXCK metacommand
  15071.  Indexed variable
  15072.  INITCK metacommand
  15073.  INPUT
  15074.  INSERT procedure
  15075.  INTEGER type
  15076.  INTEGER1 predeclared subrange
  15077.  INTEGER4 type
  15078.  Interactive files
  15079.  Interface division
  15080.  Interface implementation
  15081.  INTERRUPT attribute
  15082.  ISO Standard Pascal
  15083.  ISO standard
  15084.      minor extensions
  15085.  ISR operator
  15086.  
  15087.  
  15088.  L
  15089.  ──────────────────────────────────────────────────────────────────────────
  15090.  Label
  15091.  Labels
  15092.  LADDOK function
  15093.  Language levels
  15094.      Standard
  15095.  Lazy evaluation
  15096.  LDDRQQ function
  15097.  LDSRQQ function
  15098.  LEN field
  15099.  LEN notation
  15100.  Letters
  15101.  LINE metacommand
  15102.  LINESIZE metacommand
  15103.  LIST metacommand
  15104.  Listing file control
  15105.  Listing file format
  15106.  LMULOK function
  15107.  LN function
  15108.  LNDRQQ function
  15109.  LNSRQQ function
  15110.  LOBYTE function
  15111.  LOCKED function
  15112.  Loop label
  15113.  LOWER function
  15114.  LOWORD function
  15115.  LSTRING super array type
  15116.  LSTRINGS
  15117.      passing by reference
  15118.  
  15119.  
  15120.  M
  15121.  ──────────────────────────────────────────────────────────────────────────
  15122.  M and N formatting parameters
  15123.  M parameter
  15124.  MARKAS procedure
  15125.  MATHCK metacommand
  15126.  MAXINT predeclared constant
  15127.  MAXINT4 predeclared constant
  15128.  MAXWORD predeclared constant
  15129.  MDDRQQ function
  15130.  MDSRQQ function
  15131.  MEMAVL function
  15132.  MESSAGE metacommand
  15133.  Metacommands
  15134.      $brave
  15135.      $debug
  15136.      $decmath
  15137.      $entry
  15138.      $errors
  15139.      $extend
  15140.      $floatcalls
  15141.      $goto
  15142.      $if/$then/$else
  15143.      $include
  15144.      $inconst
  15145.      $indexck
  15146.      $initck
  15147.      $line
  15148.      $linesize
  15149.      $list
  15150.      $mathck
  15151.      $message
  15152.      $nilck
  15153.      notation
  15154.      $ocode
  15155.      optimization
  15156.      $page
  15157.      $pageif
  15158.      $pagesize
  15159.      $pop
  15160.      $push
  15161.      $rangeck
  15162.      $rom
  15163.      $runtime
  15164.      setting language level
  15165.      $size
  15166.      $skip
  15167.      $speed
  15168.      $stackck
  15169.      $subtitle
  15170.      $subtitle
  15171.      summary
  15172.      $symtab
  15173.      $system
  15174.      $tagck
  15175.      $title
  15176.      $title
  15177.      $warn
  15178.      $warn
  15179.  Metaconditional
  15180.  Metavariable
  15181.  MNDRQQ function
  15182.  MNSRQQ function
  15183.  MOD operator
  15184.  Modules
  15185.  MOVEL procedure
  15186.  MOVER procedure
  15187.  MOVESL procedure
  15188.  MOVESR procedure
  15189.  MS-Pascal
  15190.      comparison with UCSD
  15191.      comparisons with other Pascals
  15192.  MXDRQQ function
  15193.  MXSRQQ function
  15194.  
  15195.  
  15196.  N
  15197.  ──────────────────────────────────────────────────────────────────────────
  15198.  N and M formatting parameters
  15199.  N formatting parameter
  15200.  NAN (
  15201.  NEW procedure
  15202.  NEW procedure
  15203.  NILCK metacommand
  15204.  Nondecimal numbering
  15205.  NOT operator
  15206.  Not-A-Number values
  15207.  Notation
  15208.  NULL
  15209.  Null set
  15210.  Numeric constant
  15211.  
  15212.  
  15213.  O
  15214.  ──────────────────────────────────────────────────────────────────────────
  15215.  OCODE metacommand
  15216.  ODD function
  15217.  Operands
  15218.  Operators
  15219.      (>)
  15220.      (>=)
  15221.      (<>)
  15222.      (>=)
  15223.      (<>)
  15224.      (*)
  15225.      (+)
  15226.      (-)
  15227.      (<)
  15228.      (<=)
  15229.      (=)
  15230.      (*)
  15231.      (+)
  15232.      (-)
  15233.      (<=)
  15234.      (=)
  15235.      (<)
  15236.      (\)
  15237.      adding
  15238.      ADR
  15239.      ADS
  15240.      AND
  15241.      AND THEN
  15242.      div
  15243.      IN
  15244.      ISR
  15245.      mod
  15246.      multiplying
  15247.      NOT
  15248.      OR ELSE
  15249.      OR
  15250.      precedence
  15251.      relational
  15252.      SHL
  15253.      SHR
  15254.      unary
  15255.      XOR
  15256.  Optimization
  15257.  OR ELSE
  15258.  OR operator
  15259.  ORD function
  15260.  Ordinal types
  15261.  ORIGIN attribute
  15262.  OTHERWISE clause
  15263.  OUTPUT
  15264.  
  15265.  
  15266.  P
  15267.  ──────────────────────────────────────────────────────────────────────────
  15268.  PACK procedure
  15269.  PACKED
  15270.      types
  15271.      limitations
  15272.  PAGE metacommand
  15273.  PAGE procedure
  15274.  PAGEIF metacommand
  15275.  PAGESIZE metacommand
  15276.  Parameters
  15277.      actual
  15278.      formal
  15279.      function
  15280.      functional
  15281.      procedural
  15282.      procedure
  15283.      reference
  15284.      value
  15285.      VARS
  15286.  PIDRQQ function
  15287.  PISRQQ function
  15288.  PLYUQQ procedure
  15289.  POP metacommand
  15290.  PORT attribute
  15291.  POSITN function
  15292.  PPMFQQ
  15293.  PPMUQQ
  15294.  precision of REAL numbers
  15295.  PRED function
  15296.  Predeclared identifiers
  15297.  Predeclared
  15298.      constants
  15299.          maxint
  15300.          maxint4
  15301.          maxword
  15302.      functions
  15303.      procedures
  15304.      types
  15305.          ADRMEM
  15306.          ADSMEM
  15307.          FILEMODES
  15308.  Procedural parameter
  15309.  Procedural types
  15310.  Procedure block
  15311.  Procedure MOVESR
  15312.  Procedure parameters
  15313.  Procedure statement
  15314.  Procedures
  15315.      ABORT
  15316.      ASSIGN
  15317.      available
  15318.          summary of
  15319.      BEGOQQ
  15320.      BEGXQQ
  15321.      CLOSE
  15322.      CONCAT
  15323.      COPYLST
  15324.      COPYSTR
  15325.      DATE
  15326.      declarations
  15327.      DECODE
  15328.      DISBIN
  15329.      DISCARD
  15330.      DISMQQ
  15331.      DISPOSE
  15332.      ENABIN
  15333.      ENDOQQ
  15334.      ENDXQQ
  15335.      EVAL
  15336.      FILLC
  15337.      FILLSC
  15338.      GET
  15339.      heading
  15340.      INSERT
  15341.      MOVEL
  15342.      MOVER
  15343.      MOVESL
  15344.      NEW
  15345.      PACK
  15346.      PAGE
  15347.      PLYUQQ
  15348.      PUT
  15349.      READ
  15350.      READFN
  15351.      READLN
  15352.      READSET
  15353.      RELEAS
  15354.      RESET
  15355.      REWRITE
  15356.      SMULOK
  15357.      SEEK
  15358.      TIME
  15359.      UNLOCK
  15360.      UNPACK
  15361.      UPPER
  15362.      VECTIN
  15363.      WRITE
  15364.      WRITELN
  15365.  Programs
  15366.      heading
  15367.      identifiers
  15368.      parameters
  15369.  PRSRQQ function
  15370.  PSDRQQ function
  15371.  PTYUQQ procedure
  15372.  PUBLIC attribute
  15373.  Punctuation
  15374.  PURE attribute
  15375.  PUSH metacommand
  15376.  PUT procedure
  15377.  
  15378.  
  15379.  Q
  15380.  ──────────────────────────────────────────────────────────────────────────
  15381.  QQ internal naming convention
  15382.  
  15383.  
  15384.  R
  15385.  ──────────────────────────────────────────────────────────────────────────
  15386.  R address notation
  15387.  R notation
  15388.  random access files
  15389.  RANGECK metacommand
  15390.  READ formats
  15391.  READ procedure
  15392.  READFN procedure
  15393.  READLN procedure
  15394.  READONLY attribute
  15395.  READSET procedure
  15396.  REAL type
  15397.  REAL
  15398.      constants
  15399.      precision
  15400.  Records
  15401.      field offsets
  15402.      fields
  15403.      variables
  15404.  Recursion
  15405.  Reference parameters
  15406.  Reference variables
  15407.  relational operator
  15408.  RELEAS procedure
  15409.  REPEAT statement
  15410.  Repetition statement
  15411.  Reserved words
  15412.      summary
  15413.  RESET procedure
  15414.  RESULT function
  15415.  RETURN statement
  15416.  RETYPE function
  15417.  REWRITE procedure
  15418.  ROM metacommand
  15419.  ROUND function
  15420.  ROUND4 function
  15421.  RUNTIME metacommand
  15422.  
  15423.  
  15424.  S
  15425.  ──────────────────────────────────────────────────────────────────────────
  15426.  S address notation
  15427.  S address notation
  15428.  SADDOK function
  15429.  SCANEQ function
  15430.  SCANNE function
  15431.  SEEK procedure
  15432.  Segment parameters
  15433.  Semaphores
  15434.  Separators
  15435.  Sequential control
  15436.  SEQUENTIAL
  15437.  Sets
  15438.      constructors ([ and ])
  15439.      expressions
  15440.  SHDRQQ function
  15441.  SHL operator
  15442.  SHR operator
  15443.  SHSRQQ function
  15444.  Simple statement
  15445.  SIN function
  15446.  SINT predeclared subrange
  15447.  SIZE metacommand
  15448.  SIZEOF function
  15449.  SKIP metacommand
  15450.  SMULOCK procedure
  15451.  SNDRQQ function
  15452.  SNSRQQ function
  15453.  SPEED metacommand
  15454.  SQR function
  15455.  SQRT function
  15456.  SRDRQQ function
  15457.  SRSRQQ function
  15458.  STACKCK metacommand
  15459.  Standard Pascal
  15460.  Statements
  15461.      assignment
  15462.      BREAK
  15463.      CASE
  15464.      compound
  15465.      conditional
  15466.      CYCLE
  15467.      FOR
  15468.      goto
  15469.      IF
  15470.      procedure
  15471.      REPEAT
  15472.      repetition
  15473.      RETURN
  15474.      sequential control
  15475.      simple
  15476.      structured
  15477.      WHILE
  15478.      WITH
  15479.  STATIC attribute
  15480.  String constant
  15481.  String reads
  15482.  STRING super array type
  15483.  Structured constants
  15484.  Structured statements
  15485.  Structured types
  15486.  Subrange
  15487.      BYTE predeclared
  15488.      INTEGER1 predeclared
  15489.      SINT predeclared
  15490.  SUBTITLE metacommand
  15491.  SUCC function
  15492.  Super array parameters
  15493.  super array type
  15494.  Super types
  15495.  SYMTAB metacommand
  15496.  Syntactic synonym
  15497.  System level intrinsics
  15498.  System level Pascal
  15499.  SYSTEM metacommand
  15500.  
  15501.  
  15502.  T
  15503.  ──────────────────────────────────────────────────────────────────────────
  15504.  Tag field
  15505.  TAGCK metacommand
  15506.  Temporary files
  15507.  Terminal input/output routines
  15508.  TERMINAL mode
  15509.  Textfile I/O
  15510.  textfile
  15511.  THDRQQ function
  15512.  THSRQQ function
  15513.  TICS function
  15514.  TIME procedure
  15515.  TITLE metacommand
  15516.  TNDRQQ function
  15517.  TNSRQQ function
  15518.  TRUNC function
  15519.  TRUNC4 function
  15520.  Type identity and reference parameters
  15521.  Types
  15522.      ARRAY
  15523.      base
  15524.      BOOLEAN
  15525.      CHAR
  15526.      compatibility
  15527.      components
  15528.      declaration
  15529.      definition
  15530.      enumerated
  15531.      FILE
  15532.      functional
  15533.      identifiers of
  15534.      identity
  15535.      INTEGER
  15536.      INTEGER4
  15537.      LSTRING
  15538.      ordinal
  15539.      ordinal
  15540.      PACKED
  15541.      procedural
  15542.      REAL
  15543.      records
  15544.      reference parameters
  15545.      sets
  15546.      simple
  15547.      STRING
  15548.      structured
  15549.      subrange
  15550.      super arrays
  15551.      WORD
  15552.  
  15553.  
  15554.  U
  15555.  ──────────────────────────────────────────────────────────────────────────
  15556.  UADDOK function
  15557.  UCSD Pascal
  15558.  UMULOK function
  15559.  Underscore
  15560.  Units
  15561.      constituents
  15562.      identifiers
  15563.      implementations of
  15564.      interfaces
  15565.  UNLOCK procedure
  15566.  UNPACK procedure
  15567.  Unused characters
  15568.  Upper bound
  15569.  UPPER function
  15570.  
  15571.  
  15572.  V
  15573.  ──────────────────────────────────────────────────────────────────────────
  15574.  Value parameters
  15575.  VALUE section
  15576.  Variable length strings
  15577.  Variables
  15578.      attributes of
  15579.      declarations
  15580.      initial values
  15581.      reference
  15582.  VAR
  15583.      in FOR statement
  15584.      parameters
  15585.      sections
  15586.  VARS parameters
  15587.  Variant records
  15588.  VECTIN procedure
  15589.  
  15590.  
  15591.  W
  15592.  ──────────────────────────────────────────────────────────────────────────
  15593.  WARN metacommand
  15594.  WHILE statement
  15595.  WITH statement
  15596.  WORD type
  15597.  WRD function
  15598.  WRITE formats
  15599.  WRITE procedure
  15600.  WRITELN procedure
  15601.  
  15602.  
  15603.  X
  15604.  ──────────────────────────────────────────────────────────────────────────
  15605.  XOR operator
  15606.  
  15607.