home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ipo-101.zip / progref.txt < prev    next >
Text File  |  1999-02-17  |  177KB  |  5,714 lines

  1. Copyright (c) 1998, 1999 Stuart King. All rights reserved.
  2.  
  3.     Welcome to the Irie Pascal Programmer's Reference Manual
  4.  
  5. -----------------
  6. Table Of Contents
  7. -----------------
  8. 1   Introduction
  9.     1.1 Grammar Notation
  10. 2   Lexical Elements
  11.     2.1 Character Literals
  12.     2.2 String Literals
  13.     2.3 Integers
  14.     2.3.1 Decimal Integers
  15.     2.3.2 Hexadecimal Integers
  16.     2.3.3 Binary Integers
  17.     2.4 Reals
  18.     2.5 Special Symbols
  19.     2.6 Reserved Words
  20.     2.7 Identifiers
  21.     2.7.1  Directives
  22.     2.7.2  Built-in Identifiers
  23.     2.7.3  User Defined Identifiers
  24.     2.8 Comments
  25. 3   Labels
  26. 4   Constants
  27.     4.1 Boolean
  28.     4.2 MaxChar
  29.     4.3 MaxInt
  30.     4.4 Nil
  31.     4.5 Permission
  32.     4.6 Platform
  33.     4.7 FileMode
  34.     4.8 dir_bit
  35. 5   Types
  36.     5.1 Enumerated Types
  37.     5.2 Subrange Types
  38.     5.3 Pointer Types
  39.     5.4 Array Types
  40.     5.5 String Types
  41.     5.6 Record Types
  42.     5.7 Set Types
  43.     5.8 File Types
  44.     5.9 List Types
  45.     5.10 Type Identifiers
  46.     5.10.1 boolean
  47.     5.10.2 char
  48.     5.10.3 dir
  49.     5.10.4 filename
  50.     5.10.5 integer
  51.     5.10.6 real
  52.     5.10.7 text
  53. 6   Variables
  54.     6.1 Pointer Variables
  55.     6.2 Array Variables
  56.     6.3 String Variables
  57.     6.4 Record Variables
  58.     6.5 List Variables
  59. 7   Functions And Procedures
  60.     7.1 Built-in Functions
  61.     7.1.1 abs
  62.     7.1.2 arctan
  63.     7.1.3 chr
  64.     7.1.4 concat
  65.     7.1.5 copy
  66.     7.1.6 cos
  67.     7.1.7 cosh
  68.     7.1.8 eof
  69.     7.1.9 eoln
  70.     7.1.10 exp
  71.     7.1.11 fexpand
  72.     7.1.12 filepos
  73.     7.1.13 filesize
  74.     7.1.14 frac
  75.     7.1.15 getenv
  76.     7.1.16 hex
  77.     7.1.17 int
  78.     7.1.18 ioresult
  79.     7.1.19 isalpha
  80.     7.1.20 isalphanum
  81.     7.1.21 isdigit
  82.     7.1.22 islower
  83.     7.1.23 isprint
  84.     7.1.24 isspace
  85.     7.1.25 isupper
  86.     7.1.26 isxdigit
  87.     7.1.27 length
  88.     7.1.28 ln
  89.     7.1.29 log
  90.     7.1.30 locase
  91.     7.1.31 lowercase
  92.     7.1.32 odd
  93.     7.1.33 ord
  94.     7.1.34 paramcount
  95.     7.1.35 paramstr
  96.     7.1.36 pi
  97.     7.1.37 platform
  98.     7.1.38 pos
  99.     7.1.39 pred
  100.     7.1.40 random
  101.     7.1.41 reverse
  102.     7.1.42 round
  103.     7.1.43 sin
  104.     7.1.44 sinh
  105.     7.1.45 sqr
  106.     7.1.46 sqrt
  107.     7.1.47 succ
  108.     7.1.48 swap
  109.     7.1.49 system
  110.     7.1.50 tan
  111.     7.1.51 tanh
  112.     7.1.52 trim
  113.     7.1.53 trunc
  114.     7.1.54 upcase
  115.     7.1.55 uppercase
  116.     7.2 Built-in Procedures
  117.     7.2.1 append
  118.     7.2.2 assert
  119.     7.2.3 assign
  120.     7.2.4 chdir
  121.     7.2.5 close
  122.     7.2.6 closedir
  123.     7.2.7 dec
  124.     7.2.8 delete
  125.     7.2.9 dispose
  126.     7.2.10 erase
  127.     7.2.11 exec
  128.     7.2.12 exit
  129.     7.2.13 flush
  130.     7.2.14 fsplit
  131.     7.2.15 get
  132.     7.2.16 getdate
  133.     7.2.17 getfiledate
  134.     7.2.18 getfilemode
  135.     7.2.19 getfiletime
  136.     7.2.20 gettime
  137.     7.2.21 halt
  138.     7.2.22 inc
  139.     7.2.23 insert
  140.     7.2.24 mkdir
  141.     7.2.25 new
  142.     7.2.26 open
  143.     7.2.27 opendir
  144.     7.2.28 pack
  145.     7.2.29 page
  146.     7.2.30 put
  147.     7.2.31 randomize
  148.     7.2.32 rawread
  149.     7.2.33 rawwrite
  150.     7.2.34 read
  151.     7.2.35 readdir
  152.     7.2.36 readln
  153.     7.2.37 rename
  154.     7.2.38 reset
  155.     7.2.39 rewinddir
  156.     7.2.40 rewrite
  157.     7.2.41 rmdir
  158.     7.2.42 seek
  159.     7.2.43 setfiledate
  160.     7.2.44 setfiletime
  161.     7.2.45 sleep
  162.     7.2.46 str
  163.     7.2.47 unpack
  164.     7.2.48 val
  165.     7.2.49 write
  166.     7.2.50 writeln
  167. 8   Expressions
  168.     8.1 Operators
  169.     8.1.1 Not Operator
  170.     8.1.2 * Operator
  171.     8.1.3 / Operator
  172.     8.1.4 Div Operator
  173.     8.1.5 Mod Operator
  174.     8.1.6 And Operator
  175.     8.1.7 And_Then Operator
  176.     8.1.8 + Operator
  177.     8.1.9 - Operator
  178.     8.1.10 Or Operator
  179.     8.1.11 Or_Else Operator
  180.     8.1.12 Xor Operator
  181.     8.1.13 shl Operator
  182.     8.1.14 shr Operator
  183.     8.1.15 = Operator
  184.     8.1.16 <> Operator
  185.     8.1.17 < Operator
  186.     8.1.18 <= Operator
  187.     8.1.19 > Operator
  188.     8.1.20 >= Operator
  189.     8.1.21 In Operator
  190.     8.2 Compatible types
  191. 9   Statements
  192.     9.1 Empty Statement
  193.     9.2 Assignment Statement
  194.     9.2.1 Assignment Compatibility
  195.           9.2.1.1 Assignment compatibility with array indexing
  196.           9.2.1.2 Assignment compatibility with value parameters
  197.           9.2.1.3 Assignment compatibility with "read"
  198.           9.2.1.4 Assignment compatibility with assignment statements
  199.           9.2.1.5 Assignment compatibility with "for"
  200.           9.2.1.6 Transfer procedures
  201.     9.3 Procedure Statement
  202.     9.4 Goto Statement
  203.     9.5 Compound Statement
  204.     9.6 If Statement
  205.     9.7 Case Statement
  206.     9.8 Repeat Statement
  207.     9.9 While Statement
  208.     9.10 For Statement
  209.     9.11 With Statement
  210. 10  Program parameters
  211. Appendix A. Irie Pascal Grammar
  212. Appendix B. Extensions to Pascal as specified by ISO/IEC 7185
  213.     B.1 Relaxed declarations
  214.     B.2 Constant ranges
  215.     B.3 Otherwise
  216.     B.4 Relaxed parameter list congruity
  217.     B.5 Non-numeric statement labels
  218.     B.6 Underscores in identifiers
  219.     B.7 Binary integer constants
  220.     B.8 Hexadecimal integer constants
  221.     B.9 Input and Output automatically declared
  222.     B.10 Double-quoted literals
  223.     B.11 and_then operator
  224.     B.12 or_else operator
  225.     B.13 Bitwise operators
  226.      B.13.1 shl operator
  227.      B.13.2 shr operator
  228.      B.13.3 and (Bitwise) operator
  229.      B.13.4 or (Bitwise) operator
  230.      B.13.5 not (Bitwise) operator
  231.      B.13.6 xor (Bitwise) operator
  232.     B.14 Extended constants
  233.      B.14.1 maxchar
  234.      B.14.2 usr_r
  235.      B.14.3 usr_w
  236.      B.14.4 usr_x
  237.      B.14.5 grp_r
  238.      B.14.6 grp_w
  239.      B.14.7 grp_x
  240.      B.14.8 oth_r
  241.      B.14.9 oth_w
  242.      B.14.10 oth_x
  243.      B.14.11 dir_bit
  244.      B.14.12 platform_dos
  245.      B.14.13 platform_os2
  246.      B.14.14 platform_win32
  247.      B.14.15 platform_linux
  248.      B.14.16 platform_fbsd
  249.      B.14.17 platform_error
  250.      B.14.18 appendmode
  251.      B.14.19 readmode
  252.      B.14.20 writemode
  253.     B.15 Extended types
  254.      B.15.1 dir
  255.      B.15.2 filename
  256.      B.15.3 list
  257.      B.15.4 string
  258.     B.16 Extended variables
  259.      B.16.1 exitcode
  260.  
  261. ----------------
  262. 1   Introduction
  263. ----------------
  264. This is the Irie Pascal Programmer's Reference Manual, and describes
  265. the Irie Pascal language. This manual is not a tutorial and does not
  266. attempt to teach programming. If you are new to programming or new to
  267. Pascal you may need additional information. Fortunately there are many
  268. excellent books which teach programming in Pascal. If you decide to
  269. purchase a Pascal book, you should look for one that covers Standard
  270. Pascal. For information on how to install and use Irie Pascal, see the
  271. Irie Pascal User's Manual which should accompany this manual.
  272.  
  273. --------------------
  274. 1.1 Grammar Notation
  275. --------------------
  276. Context-free grammars are often used to define the syntax of programming
  277. languages because they produce short and precise definitions. A
  278. context-free grammar breaks the syntax of a complex language into a
  279. number of simpler elements called non-terminal symbols. The syntax of
  280. each non-terminal symbol is defined by a production. Each production
  281. consists of a non-terminal symbol followed by some sort of assignment
  282. operator, and then followed by a sequence of special symbols, terminal
  283. symbols and non-terminal symbols. The special symbols are used to describe
  284. how the other symbols can be combined. The terminals symbols are literal
  285. text that can occur in the language being defined. The full context-free
  286. grammar takes the form of a sequence of productions for all the non-terminal
  287. symbols in the language.
  288.  
  289. The context-free grammar used in this manual has the following notation.
  290. The equal sign is used as the assignment operator in productions to
  291. separate the non-terminal symbol being defined from it's definition.
  292. The special symbols are |, {}, [], and (). The | symbol is used to separate
  293. alternatives (i.e. the grammar allows either the symbols on it's left-hand
  294. side or the symbols on it's right-hand side). The {} symbols are used to
  295. enclose symbols that can be repeated zero, one, or more times. The []
  296. symbols are used to enclose optional symbols (i.e. the grammar allows the
  297. enclosed symbols to either occur once or not occur at all). The () symbols
  298. are used to group symbols that are evaluated together.
  299. The terminal symbols are enclosed in single quotes ('') to distinguish them
  300. For example here are the productions that define the syntax for identifiers.
  301.  
  302.    identifier = letter { letter | digit }
  303.  
  304.    letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' |
  305.         'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' |
  306.         'u' | 'v' | 'w' | 'x' | 'y' | 'z' |
  307.         'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' |
  308.         'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' |
  309.         'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' |
  310.         '_'
  311.  
  312.    digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
  313.  
  314. The productions mean:
  315. An identifier is a letter followed by zero or more letter or digits.
  316. A letter is a lower-case letter or an upper-case letter or an underscore.
  317. A digit is one of the decimal numerals.
  318.  
  319. The complete grammar for Irie Pascal is given in Appendix A.
  320.  
  321. --------------------
  322. 2   Lexical Elements
  323. --------------------
  324. This chapter describes the elements that make up programs.
  325.  
  326. ----------------------
  327. 2.1 Character Literals
  328. ----------------------
  329. A character literal is a character enclosed in single quotes (') or
  330. as an extension in double quotes ("). Two single quotes together can be
  331. used to represent single quotes in character literals enclosed in single
  332. quotes. Two double quotes together can be used to represent double quotes
  333. in character literals enclosed in double quotes.
  334. So   "'" and '''' are both character literals containing single quotes.
  335. And """" and '"' are both character literals containing double quotes.
  336.  
  337. Character literals are case-sensitive so 'X' is not equal to 'x'.
  338. The syntax for character literals is as follows
  339.  
  340.    character-literal = ''' string-element-one ''' |
  341.                '"' string-element-two '"'
  342.  
  343.    string-element-one = '''' | printable-character
  344.  
  345.    string-element-two = '""' | printable-character
  346.  
  347.    printable-character = any character (including a space) that has a visual
  348.              representation.
  349.  
  350. NOTE: The production for printable-character doesn't follow the usual
  351. notation because 1) its tedious to write out every possible printable
  352. character and 2) the definition for a printable character depends on
  353. the character set being used.
  354.  
  355. Here are some examples of valid character literals:
  356.    'A'    '+'    ' '    ''''     '"'
  357.    "A"    "+"    " "    "'"      """"
  358.  
  359. -------------------
  360. 2.2 String Literals
  361. -------------------
  362. A string literal is a sequences of zero, two or more characters enclosed in
  363. single quotes (') or as an extension in double quotes. Literals with
  364. one character are character literals not string literals. Two single quotes
  365. together can be used to represent single quotes in string literals enclosed
  366. in single quotes. Two double quotes together can be used to represent
  367. double quotes in string literals enclosed in double quotes. So
  368. "Don't" and 'Don''t' are both string literals containing   Don't.
  369. String literals are case-sensitive, so 'Hello' is not equal to 'HELLO'.
  370. There is no explicit limit on the length of string literals but since
  371. string literals can not span more than one line, then the limit on the
  372. length of a line (400) implicitly limits the length of string literals.
  373.  
  374. The syntax for string literals is as follows
  375.  
  376.    string-literal = empty-string | other-string
  377.  
  378.    empty-string = '''' | '""'
  379.  
  380.    other-string =
  381.        ''' string-element-one string-element-one {string-element-one ''' |
  382.        '"' string-element-two string-element-two {string-element-two '"'
  383.  
  384.    string-element-one = '''' | printable-character
  385.  
  386.    string-element-two = '""' | printable-character
  387.  
  388.    printable-character = any character (including a space) that has a visual
  389.              representation.
  390.  
  391. NOTE: The production for printable-character doesn't follow the usual
  392. notation because 1) its tedious to write out every possible printable
  393. character and 2) the definition for a printable character depends on
  394. the character set being used.
  395.  
  396. Here are some examples of valid string literals:
  397.    ''     '   '  'Don''t'        'Say "Hello"'     '!@#$%^&*()'
  398.    ""     "   "  "Don't"         "Say ""Hello"""   "!@#$%^&*()"
  399.  
  400. ------------
  401. 2.3 Integers
  402. ------------
  403. Integers are whole numbers (i.e. numbers with no fractional part).
  404. Leading zeroes are not significant in integers.
  405.  
  406. The syntax for integers is
  407.  
  408.    integer = decimal-integer |
  409.          hexadecimal-integer |
  410.          binary-integer
  411.  
  412. Irie Pascal supports integers with values between
  413.     -2147483647  and  +2147483647
  414.  
  415. ----------------------
  416. 2.3.1 Decimal Integers
  417. ----------------------
  418. A decimal integer is a base 10 whole number.
  419.  
  420. The syntax for decimal integers is as follows:
  421.  
  422.    decimal-integer = [sign] digit { digit }
  423.  
  424.    sign = [ '+' | '-' ]
  425.  
  426.    digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
  427.  
  428. Here are some examples of valid decimal integers
  429.  
  430.    100     -0      +7453    000005
  431.  
  432. --------------------------
  433. 2.3.2 Hexadecimal Integers
  434. --------------------------
  435. As an extension Irie Pascal supports hexadecimal (base 16) integers.
  436.  
  437. The syntax for hexadecimal integers is as follows:
  438.  
  439.    hexadecimal-integer = [sign] '$' hex-digit { hex-digit }
  440.  
  441.    sign = [ '+' | '-' ]
  442.  
  443.    digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
  444.  
  445.    hexdigit = digit |
  446.           'a' | 'b' | 'c' | 'd' | 'e' | 'f' |
  447.           'A' | 'B' | 'C' | 'D' | 'E' | 'F'
  448.  
  449. Here are some examples of valid hexadecimal integers
  450.  
  451.    $64     -$0      +$FF       -$000ab4
  452.  
  453. ---------------------
  454. 2.3.3 Binary Integers
  455. ---------------------
  456. As an extension Irie Pascal supports binary (base 2) integers.
  457.  
  458. The syntax for binary integers is as follows:
  459.  
  460.    binary-integer = [sign] '%' bit { bit }
  461.  
  462.    sign = [ '+' | '-' ]
  463.  
  464.    bit = '0' | '1'
  465.  
  466. Here are some examples of valid binary integers
  467.  
  468.    %01100110     -%0      +%11111111
  469.  
  470. ---------
  471. 2.4 Reals
  472. ---------
  473. Reals are numbers with fractional parts. Leading zeroes are not significant
  474. in reals.
  475.  
  476. The syntax for reals is as follows
  477.  
  478.    real = [sign] unsigned-real
  479.  
  480.    sign = [ '+' | '-' ]
  481.  
  482.    unsigned-real =
  483.        digit-sequence '.' fractional-part [ exponent scale-factor ] |
  484.        digit-sequence exponent scale-factor
  485.  
  486.        digit-sequence = digit { digit }
  487.  
  488.        fractional-part = digit-sequence
  489.  
  490.        exponent = 'e' | 'E'
  491.  
  492.        scale-factor = [ sign ] | digit-sequence
  493.  
  494. Here are some examples of real numbers:
  495.    -1.23456e2   which is equal to -123.456
  496.    -1.23456e02  which is also equal to -123.456
  497.    009863434455e-07   which is equal to 986.3434455
  498.    7e-1 which is equal to 0.7
  499.  
  500. Irie Pascal supports reals with values between
  501. about   1e308        and about        -1e308
  502.  
  503. -------------------
  504. 2.5 Special Symbols
  505. -------------------
  506. Special symbols have special meanings to the compiler.
  507.  
  508. The syntax for special symbols is given below:
  509.  
  510.    special-symbol =
  511.      '+' | '-' | '*' | '/' |
  512.      '=' | '<>' | '<' | '<=' | '>' | '>=' |
  513.      '(' | ')' |
  514.      '[' | ']' | '(.' | '.)' |
  515.      ':=' | '.' | ',' | ';' | '..' |
  516.      '^' | '@'
  517.    
  518. ------------------
  519. 2.6 Reserved Words
  520. ------------------
  521. Keywords have pre-defined and fixed meanings to the compiler.
  522. The case of keywords is usually not significant so although the
  523. syntax below uses all lowercase letters for keywords the compiler will
  524. by default recognize keywords regardless of the case of the letters.
  525. NOTE: There is a compiler option (-p) that will make identifiers
  526. and keywords case-sensitive.
  527.  
  528. The syntax for keywords is given below:
  529.  
  530.    keywords := 'and' | 'and_then' | 'array' |
  531.            'begin' |
  532.            'case' | 'const' |
  533.            'div' | 'do' | 'downto' |
  534.            'else' | 'end' |
  535.            'file' | 'for' | 'function' |
  536.            'goto' |
  537.            'if' | 'in' |
  538.            'label' | 'list'
  539.            'mod' |
  540.            'nil' | 'not' |
  541.            'of' | 'or' | 'or_else' | 'otherwise' |
  542.            'packed' | 'procedure' | 'program' |
  543.            'record' | 'repeat' |
  544.            'set' | 'shl' | 'shr' |
  545.            'then' | 'to' | 'type' |
  546.            'until' |
  547.            'var' |
  548.            'while' | 'with' |
  549.            'xor'
  550.  
  551. Attempts to declare an identifier with the same name as a keyword will
  552. be rejected by the compiler.
  553.  
  554. ---------------
  555. 2.7 Identifiers
  556. ---------------
  557. Identifiers are sequences of letters and digits that start with a letter.
  558. As an extension, Irie Pascal also supports identifiers that contain
  559. and/or start with underscores (_). By default identifiers are not
  560. case-sensitive so
  561.        x    and     X
  562. are normally considered to be the same identifier. NOTE: There is a
  563. compiler option (-p) that will make keywords and identifiers case-sensitive.
  564. Some programmers prefer case-sensitive languages since these consider
  565. identifiers that differ only in case to be different identifiers. This
  566. is often used to allow strongly related identifiers to have the same
  567. "spelling" (i.e. differ only in case).
  568. For example consider the code fragment below.
  569.  
  570. type
  571.    STUDENT = record
  572.       name : string;
  573.       address : string;
  574.       grade : integer;
  575.    end;
  576. var
  577.    student : STUDENT;
  578.  
  579. The use of the same "spelling" for the variable "student" and it's
  580. type "STUDENT" emphasize the connection between the two.
  581.  
  582. You should use this compiler option with caution (or not at all) since
  583. this feature of Irie Pascal is not supported by many (if any) other
  584. Pascal compilers.
  585.  
  586. The syntax for identifiers is given below:
  587.  
  588.    identifier = letter { letter | digit }
  589.  
  590.    letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' |
  591.         'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' |
  592.         'u' | 'v' | 'w' | 'x' | 'y' | 'z' |
  593.         'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' |
  594.         'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' |
  595.         'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' |
  596.         '_'
  597.  
  598.    digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
  599.  
  600. -----------------
  601. 2.7.1  Directives
  602. -----------------
  603. Directives are special identifiers that can be used to give the compiler
  604. extra information about a declaration. The compiler recognizes directives
  605. only at specific points in a declaration, and this recognition is not
  606. affected by and does not affect, any meaning the directive's identifier may
  607. have outside of these specific points. So for example the "forward"
  608. directive is recognized even if the identifier "forward" has been declared
  609. to have some other meaning, and the use of the "forward" directive does
  610. not affect any meaning that "forward" has been declared to have.
  611.  
  612. NOTE: Irie Pascal currently supports only the "forward" directive
  613. (see "7 Functions and Procedures" for more information).
  614.  
  615.  
  616. ---------------------------
  617. 2.7.2  Built-in Identifiers
  618. ---------------------------
  619. Built-in identifiers are automatically declared by the compiler.
  620. Unlike keywords, you can declare identifiers with the same name as
  621. built-in identifiers, if you do then your declaration will override the
  622. declaration made by the compiler. So for example the following declaration
  623.  
  624.    type
  625.       boolean = (no, yes);
  626.  
  627. will override the declaration given by the compiler
  628.    type
  629.       boolean = (false, true);
  630.  
  631. Some built-in identifiers are extensions and are therefore only
  632. declared when extensions are enabled.
  633.  
  634. -------------------------------
  635. 2.7.3  User Defined Identifiers
  636. -------------------------------
  637. User defined identifiers are created and bound to program entities using
  638. declarations. You can then reference the entities using the identifiers.
  639. Identifiers can be bound to the following kinds of entities:
  640.    Labels, Constants, Types, Variables, Procedures, and Functions.
  641.  
  642. ------------
  643. 2.8 Comments
  644. ------------
  645. Comments are sequences of characters enclosed in 
  646.       {      or       (* 
  647. and
  648.       }      or       *)
  649.  
  650. Comments are treated like spaces by the compiler and therefore have no
  651. effect on your program except possible to separate identifiers
  652. (e.g.   the compiler treats i(* comment *)j   like two separate
  653. identifiers        i j    and not a single identifier   ij).
  654.  
  655. By default comments can not be nested (i.e. by default comments can not
  656. contain other comments). So comments like
  657.  
  658.    (* outer (* inner comment *) comment *)
  659.  
  660. will be terminated at the first close comment marker, like below
  661.  
  662.    (* outer (* inner comment *)
  663.  
  664. the last part
  665.  
  666.     comment *)
  667.  
  668. will not be treated as part of the comment and will cause a syntax
  669. error.
  670.  
  671. There is a compiler option (-nc) that causes the compiler to support
  672. nested comments. When this compiler option is enabled the compiler
  673. recognizes the end of comments only when the number of close comment
  674. markers matches the number of open comment markers. So the example
  675. comment above will terminate only after the second *).
  676.  
  677. Both open comment markers (* and { are considered to be equivalent,
  678. and both close comment markers *) and } are considered to be equivalent.
  679. So attempting to trick the compiler into accepting nested comments with
  680. something like
  681.  
  682.    (* outer { inner comment } comment *)
  683.  
  684. will not work.
  685.  
  686. Nested comments are disabled by default since in Standard Pascal comments
  687. do not nest.
  688.  
  689. ----------
  690. 3   Labels
  691. ----------
  692. Labels are markers which you can place in front of statements so that
  693. the statements can be referenced by "goto" statements. Labels can
  694. be digit sequences or as an extension identifiers. Leading zeroes
  695. are not significant in labels which are digit sequences, so "009" and "9"
  696. are the same label.
  697.  
  698. Labels must be declared (in a label declaration group) before they can be
  699. used.
  700.  
  701. The syntax for label declaration groups is given below:
  702.  
  703.    label-declaration-group = 'label' label { ',' label } ';'
  704.  
  705.    label = digit-sequence | identifier
  706.  
  707. -------------
  708. 4   Constants
  709. -------------
  710. Constants can be character literals, string literals, integers, reals,
  711. or constant identifiers. Character and string literals, integers, and reals
  712. have already been described in previous sections
  713. (See "2.1 Character Literals", "2.2 String Literals", "2.3 Integers",
  714. and "2.4 Reals").
  715. Constant identifiers are identifiers that have been bound to a constant
  716. using a constant declaration.
  717.  
  718. Constant declarations must be placed in constant declaration groups.
  719.  
  720. The syntax for constant declaration groups is given below:
  721.  
  722.    constant-declaration-group =
  723.      'const' constant-declaration ';' { constant-declaration ';' }
  724.  
  725.    constant-declaration = identifier '=' constant
  726.  
  727.    constant = integer | real | character-literal | string-literal |
  728.           constant-identifier
  729.  
  730. Here is an example of a constant definition group:
  731.  
  732. const
  733.    Space = ' ';
  734.    message = 'Hello';
  735.    first = 1;
  736.    last = 10;
  737.    DaysInYear = 365.25;
  738.    minint = -maxint;
  739.  
  740. -----------
  741. 4.1 Boolean
  742. -----------
  743. Irie Pascal supports two built-in enumerated constants "false" and "true"
  744. which are associated with the built-in type "boolean". The ordinal value
  745. of "false" is zero and the ordinal value of "true" is one.
  746.  
  747. -----------
  748. 4.2 MaxChar
  749. -----------
  750. As an extension Irie Pascal supports the built-in character constant
  751. "maxchar" which is equal to the largest character value supported by
  752. Irie Pascal.
  753.  
  754. ----------
  755. 4.3 MaxInt
  756. ----------
  757. Irie Pascal supports the built-in integer constant "maxint" which is
  758. equal to the largest supported integer value.
  759.  
  760. -------
  761. 4.4 Nil
  762. -------
  763. Irie Pascal supports a built-in constant "nil" associated with all pointer
  764. types, this constant can be assigned to any pointer variable to indicate
  765. that the variable doesn't point anywhere. Any pointer variable can also
  766. be compared with "nil".
  767.  
  768. --------------
  769. 4.5 Permission
  770. --------------
  771. As an extension Irie Pascal supports nine built-in integer constants which
  772. can be used with the built-in procedures "mkdir" and "getfilemode" to
  773. specify or identify read, write, and execute permissions. Three constants
  774. "usr_r", "usr_w", and "usr_x" specify or identify user read, write,
  775. and execute permissions respectively (i.e. permissions associated with the
  776. file or directories owner). Three constants "grp_r", "grp_w", and "grp_x"
  777. specify or identify group read, write, and execute permissions
  778. respectively (i.e. permissions associated with users belonging to the
  779. file or directories owner's group). Three constants "oth_r", "oth_w",
  780. and "oth_x" specify or identify other read, write, and execute permissions
  781. respectively (i.e. permissions associated with users who do not belong
  782. to the file or directory owner's group).
  783.  
  784. ------------
  785. 4.6 Platform
  786. ------------
  787. As an extension Irie Pascal supports four integer constants "platform_dos",
  788. "platform_os2", "platform_win32", and "platform_linux" which can be
  789. compared with the value returned by the built-in function "platform" to
  790. determine the platform your program is running on.
  791.  
  792. ------------
  793. 4.7 FileMode
  794. ------------
  795. As an extension Irie Pascal supports three integer constants "readmode",
  796. "writemode", and "appendmode" which can be used with the built-in "open"
  797. procedure to specify the mode the file should be opened in.
  798. See also "7.2.26 open".
  799.  
  800. -----------
  801. 4.8 dir_bit
  802. -----------
  803. As an extension Irie Pascal supports the integer constant "dir_bit",
  804. which can be AND'd with "mode" returned by "getfilemode" to determine
  805. if a file is a directory.
  806.  
  807. ---------
  808. 5   Types
  809. ---------
  810. Types specify sets of valid values, and every constant, variable and
  811. function return value is associated with a specific type. Most types must
  812. be defined before they can be used, the exceptions to this rule are pointer
  813. types. Pointer types are allowed to be used before they are defined to
  814. allow self-referencing structures (such as linked lists) to be built.
  815.  
  816. Irie Pascal supports the following types:
  817.    enumerated types, subrange types, pointer types, array types,
  818.    string types, record types, set types, file types, list types,
  819.    type-identifiers
  820.  
  821. Type identifiers are identifiers that have been bound to a type
  822. using a type declaration.
  823.  
  824. Type declarations must be placed in type declaration groups.
  825.  
  826. The syntax for type declaration groups is given below:
  827.  
  828.    type-declaration-group =
  829.     'type' identifier '=' type-declaration ';' { type-declaration ';' }
  830.  
  831.    type-declaration = identifier '=' type-denoter
  832.  
  833.    type-denoter = type-identifier | new-type
  834.  
  835.    type-identifier = identifier
  836.  
  837.    new-type = new-ordinal-type | new-structured-type | new-pointer-type
  838.  
  839.    new-ordinal-type = enumerated-type | subrange-type
  840.  
  841.    new-structured-type = [ 'packed' ] array-type |
  842.              [ 'packed' ] record-type |
  843.              [ 'packed' ] set-type |
  844.              [ 'packed' ] file-type |
  845.              [ 'packed' ] list-type |
  846.                       string-type
  847.  
  848.    new-pointer-type = '^' domain-type |
  849.               '@' domain-type
  850.  
  851.    domain-type = type-identifier
  852.  
  853. Here is an example of a type declaration group:
  854.  
  855. type
  856.    symbols = record
  857.       name : string;
  858.       value : integer;
  859.    end;
  860.    SymbolTable = list of symbols;
  861.    color = (red, green, blue);
  862.    cardinal = 0..maxint;
  863.    IntegerList = array[1..100] of integer;
  864.    characters = set of char;
  865.  
  866. --------------------
  867. 5.1 Enumerated Types
  868. --------------------
  869. Enumerated types specify a finite set of ordered values. Each of these
  870. ordered values is associated with an identifier (a enumerated constant)
  871. and has integer type.
  872.  
  873. The syntax for enumerated types is given below:
  874.  
  875.    enumerated-type = '(' identifier-list ')'
  876.  
  877.    identifier-list = identifier { ',' identifier }
  878.  
  879. Here are some examples of enumerated types
  880.  
  881.    (red, blue, green)
  882.    (low, medium, high)
  883.    (married, divorced, widowed, single)
  884.  
  885. ------------------
  886. 5.2 Subrange Types
  887. ------------------
  888. Subrange types specify a contiguous subset of an ordinal type. This
  889. ordinal type is known as the host type and the values of a subrange
  890. type have the same type as it's host type.
  891.  
  892. The syntax for subrange types is give below:
  893.  
  894.    subrange-type = constant '..' constant
  895.  
  896. Here are some examples of subrange types:
  897.  
  898.    -100..+100
  899.    true..true
  900.    'a'..'z'
  901.  
  902. -----------------
  903. 5.3 Pointer Types
  904. -----------------
  905. Pointer types specify the special value "nil" and a set of values
  906. identifying variables associated with them. The built-in procedure
  907. "new" creates a pointer variable and associates it with the variables type.
  908. The built-in procedure "dispose" destroys a pointer variable and
  909. disassociates it from the variables type.
  910.  
  911. The syntax for pointer types is given below:
  912.  
  913.    pointer-type = '^' domain-type |
  914.           '@' domain-type
  915.  
  916.    domain-type = type-identifier
  917.  
  918. Here are some examples of pointer types:
  919.  
  920.    ^integer
  921.    ^real
  922.  
  923. ---------------
  924. 5.4 Array Types
  925. ---------------
  926. Array types specify collections of values of the same type (called
  927. the array's component type) and associates an index type with the
  928. collections. Each member of an array's collection is called an array
  929. element and is identified by a value of the array's index type.
  930. An array's component type may itself be an array, and the component
  931. type of the component type may also be an array. It is sometimes
  932. easier to think about an array of arrays as a multi-dimensional
  933. array (i.e. an array specifying a collection with an axis for each
  934. array component, where each element is identified by values from
  935. each component arrays index type).
  936.  
  937. Packed arrays of char having a lower bound of one and an upper bound
  938. of two or greater are fixed length strings and have special properties.
  939. Normally values of array types can be tested for equality and inequality
  940. but can not be tested to see whether one is less than the other. Fixed
  941. length strings can be tested not only for equality and inequality but
  942. also can be tested to see whether one is less than the other. Fixed
  943. length strings unlike other arrays can also be read from and written to
  944. text files as a unit using the built-in procedures "read",
  945. "readln", "write", and "writeln".
  946.  
  947. The syntax for array types is given below
  948.  
  949.     array-type = 'array' '[' index-type-list ']' 'of' component-type
  950.  
  951.     index-type-list = index-type { ',' index-type }
  952.  
  953.     index-type = ordinal-type
  954.  
  955.     ordinal-type = enumerated-type |
  956.            subrange-type |
  957.            ordinal-type-identifier
  958.  
  959.     component-type = type-denoter
  960.  
  961. Here are some examples of array types:
  962.  
  963.     array[1..10] of real
  964.     array[char] of boolean
  965.     array[-456..-450] of integer
  966.  
  967. NOTE:
  968. As a shorthand notation a multi-dimensional array type can be created
  969. by listing the index types of each of the component arrays.
  970. In other words
  971.  
  972.     array[1..10, char, boolean] of integer
  973.  
  974. is a shorthand notation for
  975.  
  976.     array[1..10] of array[char] of array[boolean] of integer
  977.  
  978. ----------------
  979. 5.5 String Types
  980. ----------------
  981. As an extension Irie Pascal supports variable length strings using the
  982. built-in type "string". Variable length strings specify collections of
  983. characters whose length does not exceed a maximum value.
  984.  
  985. The syntax for string types is given below:
  986.  
  987.    string-type = 'string' |
  988.          'string' '[' size ']' |
  989.          'string' '(' size ')'
  990.  
  991.    size = integer
  992.  
  993. where
  994.    size is an integer constant, between 1 and 1048576, which specifies the
  995.    maximum length of the string. If size is not specified the maximum
  996.    length used is 255.
  997.  
  998. For example to create a variable length string type called "name" with
  999. a maximum length of 80 use
  1000.    name = string[80];
  1001. or
  1002.    name = string(80);
  1003. To create a variable length string type called 'address' with a maximum
  1004. length of 255 use
  1005.    address = string;
  1006. or
  1007.    address = string[255];
  1008. or
  1009.    address = string(255);
  1010.  
  1011. ----------------
  1012. 5.6 Record Types
  1013. ----------------
  1014. Record types specify collections of values. A record type may be empty
  1015. (i.e. specify a collection with no values). Each member of a record
  1016. type's collection is called a field and is identified by a field
  1017. identifier, with the possible exception of the variant selector which
  1018. sometimes does not have a field identifier. Each member in a record's
  1019. collection has a particular type (which can be a record type).
  1020.  
  1021. Sometimes groups of fields in a record type are mutually exclusive.
  1022. You can use a variant part in a record type to specify mutually
  1023. exclusive groups of fields (these mutually exclusive groups are
  1024. called variants). Each variant part contains a variant selector,
  1025. the value of the variant selector determines which variant if any
  1026. is active.
  1027.  
  1028. The syntax for record types is given below:
  1029.  
  1030.     record-type = 'record' field-list 'end'
  1031.  
  1032.     field-list = fixed-part ';' variant-part [ ';' ] |
  1033.          fixed-part [ ';' ] |
  1034.          variant-part [ ';' ] |
  1035.          empty
  1036.  
  1037.     fixed-part = record-section { ';' record-section }
  1038.  
  1039.     record-section = id-list ':' type-denoter
  1040.  
  1041.     id-list = identifier { ',' identifier }
  1042.  
  1043.     variant-part = 'case' variant-selector 'of' variant-body
  1044.  
  1045.     variant-selector = [ identifier ':' ] ordinal-type-identifier
  1046.  
  1047.     variant-body = variant-list [ [;] variant-part-completer ] |
  1048.            variant-part-completer
  1049.  
  1050.     variant-list = variant { ';' variant }
  1051.  
  1052.     variant = case-constant-list ':' '(' field-list ')'
  1053.  
  1054.     case-constant-list = case-specifier { ',' case-specifier }
  1055.  
  1056.     case-specifier = case-constant [ '..' case-constant ]
  1057.  
  1058.     case-constant = ordinal-constant
  1059.  
  1060.     variant-part-completer = 'otherwise' '(' field-list ')'
  1061.  
  1062. Here are some examples of valid record types:
  1063.  
  1064.     record end
  1065.     record ; end
  1066.  
  1067. The record types above are empty.
  1068.  
  1069.     record
  1070.       name : string;
  1071.       grade : integer;
  1072.     end
  1073.  
  1074. The record type above has two fields which are identified by
  1075. "name" of type "string" and "grade" of type "integer".
  1076.  
  1077. Given the type below
  1078.  
  1079.     type
  1080.        clothes = (shoe, pants, shirt);
  1081.  
  1082. the following record type is valid
  1083.  
  1084.     record
  1085.     price : real;
  1086.     case kind : clothes of
  1087.        shoe : ( size : integer; );
  1088.        pants : ( waist, length : integer );
  1089.        shirt : ( neck : integer; sleeve : integer )
  1090.     end
  1091.  
  1092. and contain seven fields
  1093.  
  1094. "price", "kind", "size", "waist", "length", "neck", and "sleeve".
  1095.  
  1096. The fields "price" and "kind" are always present and the value of the
  1097. field "kind" determine which of the variants if any is present. The
  1098. variants are ("size") and ("waist" and "length") and ("neck" and "sleeve").
  1099.     
  1100. -------------
  1101. 5.7 Set Types
  1102. -------------
  1103. Set types specify combination of values of the same ordinal type
  1104. (called the set's base type). The same value can not appear more
  1105. than once. A set can be empty (i.e. have no values).
  1106.  
  1107. The syntax for set types is given below:
  1108.  
  1109.    set-type = 'set' 'of' ordinal-type
  1110.  
  1111. Here are some examples of set types
  1112.  
  1113.    set of char
  1114.    set of boolean
  1115.  
  1116. --------------
  1117. 5.8 File Types
  1118. --------------
  1119. File types specify collections of values that are persistent (i.e. they
  1120. remain stored when your program is not running) and have the same type
  1121. (called the file's component type). File component types can not be file
  1122. types or types which contain file types.
  1123.  
  1124. The syntax for file types is given below:
  1125.  
  1126.    file-type = 'file' 'of' component-type
  1127.  
  1128. --------------
  1129. 5.9 List Types
  1130. --------------
  1131. As an extension Irie Pascal supports list types. List types are ordered
  1132. collections values of a single type (called the list's component type).
  1133. Each member of a list's collection is identified by it's position in
  1134. the list.
  1135.  
  1136. The syntax for list types is given below:
  1137.  
  1138.    list-type = 'list' 'of' component-type
  1139.  
  1140. ---------------------
  1141. 5.10 Type Identifiers
  1142. ---------------------
  1143. A type identifier is an identifier that is bound to a type with a type
  1144. definition.
  1145.  
  1146. The following built-in type identifiers are supported by Irie Pascal:
  1147.    boolean, char, integer, real, filename, text, dir
  1148.  
  1149. --------------
  1150. 5.10.1 boolean
  1151. --------------
  1152. "boolean" is a built-in enumerated type with two values "false" and "true".
  1153. The ordinal value of "false" is zero and the ordinal value of "true" is
  1154. one. The conditional statement "if" and the looping statements "while"
  1155. and "repeat/until" use boolean expressions. The operators "and", "or",
  1156. "not", "and_then", "or_else" operate on boolean expressions.
  1157.  
  1158. -----------
  1159. 5.10.2 char
  1160. -----------
  1161. "char" is a built-in ordinal type with values of the current character
  1162. set.
  1163.  
  1164. ----------
  1165. 5.10.3 dir
  1166. ----------
  1167. As an extension Irie Pascal supports the built-in type "dir" whose
  1168. values are directory handles
  1169. (See also "7.2.27 opendir", "7.2.35 readdir", "7.2.39 rewinddir",
  1170. and "7.2.6 closedir").
  1171.  
  1172. ---------------
  1173. 5.10.4 filename
  1174. ---------------
  1175. As an extension Irie Pascal supports the built-in string type "filename"
  1176. which is the recommended type for variables used to store file and
  1177. directory names.
  1178.  
  1179. --------------
  1180. 5.10.5 integer
  1181. --------------
  1182. "integer" is a built-in ordinal type whose values are whole numbers
  1183. (see also "2.3 Integers").
  1184.  
  1185. -----------
  1186. 5.10.6 real
  1187. -----------
  1188. "real" is a built-in type whose values are numbers with fractional parts
  1189. (see also "2.4 Reals").
  1190.  
  1191. -----------
  1192. 5.10.7 text
  1193. -----------
  1194. "text" is a built-in file type whose values are sequences of lines.
  1195. A line is a sequence of characters and every lines in a "text" file
  1196. is terminated by an end-of-line character except possibly the last line.
  1197.  
  1198. -------------
  1199. 6   Variables
  1200. -------------
  1201. Variables are typed storage locations, and store values of their types.
  1202. Variables must be declared before they are used. Variable identifiers are
  1203. identifiers that have been bound to a variable using a variable
  1204. declaration. Variable declarations must occur in variable declaration
  1205. groups.
  1206.  
  1207. The syntax for variable declaration groups is given below:
  1208.  
  1209.    variable-declaration-group =
  1210.       'var' variable-declaration { ';' variable-declaration }
  1211.  
  1212.    variable-declaration = identifier-list ':' type-denoter
  1213.  
  1214.    identifier-list = identifier { ',' identifier }
  1215.  
  1216. ---------------------
  1217. 6.1 Pointer Variables
  1218. ---------------------
  1219. Pointer variables store either the special value "nil" or a reference to
  1220. another variable. The built-in procedure "new" is used to create variables
  1221. referenced by pointer variables. The built-in procedure "dispose" is used
  1222. to destroy variables referenced by pointer variables.
  1223.  
  1224. -------------------
  1225. 6.2 Array Variables
  1226. -------------------
  1227. Array elements can be accessed using the notation
  1228.    ArrayName[Index]
  1229. where "ArrayName" is the name of the array variable and "Index" is an
  1230. expression whose value is one of the values specified by the array's
  1231. index type (see also "5.4 Array Types"). You can use either this notation
  1232.    ArrayName[Index1][Index2]...[IndexN]
  1233. or this notation
  1234.    ArrayName[Index1, Index2,...IndexN]
  1235. to access array elements in multi-dimensional array variables.
  1236.  
  1237. --------------------
  1238. 6.3 String Variables
  1239. --------------------
  1240. The individual characters in a string variable can be accessed using
  1241. array notation. For example if "name" is a string variable then
  1242.  
  1243.    name[2]
  1244.  
  1245. accesses the second character in the string stored in "name".
  1246.  
  1247. You can use the following built-in procedures and functions to
  1248. manipulate variables of string types:
  1249.    concat, copy, length, lowercase, pos, reverse, trim, uppercase,
  1250.    delete, insert, str, val
  1251.  
  1252. You can use the "+" operator to perform string concatenation.
  1253. For example here is a hello world program using string concatenation.
  1254.  
  1255.    program good(output);
  1256.    begin
  1257.       writeln('hello' + ' ' + 'world' + '!')
  1258.    end.
  1259.  
  1260. --------------------
  1261. 6.4 Record Variables
  1262. --------------------
  1263. Record variable fields can be accessed using the following notation
  1264.    RecordName.FieldName
  1265. where "RecordName" is the name of the record variable
  1266. and "FieldName" is the name of the field.
  1267.  
  1268. ------------------
  1269. 6.5 List Variables
  1270. ------------------
  1271. You can use the following built-in procedures and functions with
  1272. variables of list types:
  1273.    new, dispose, insert, delete, length
  1274.  
  1275. You can access the components of a list variable just like an array
  1276. variable. The syntax is
  1277.      list-variable '[' integer-expression ']'
  1278. where
  1279.      integer-expression is an expression of integer type that specifies
  1280.      the position in the list of the component being accessed.
  1281. For example if "i" is an integer and "lv" is a list variable the
  1282. statement below will write each component of "lv".
  1283.      for i := 1 to length(lv) do
  1284.     writeln(lv[i])
  1285.  
  1286. ----------------------------
  1287. 7   Functions And Procedures
  1288. ----------------------------
  1289. Pascal encourages modular programming (i.e. creating a complex
  1290. program from smaller and simpler modules). Ideally these modules
  1291. should resemble so called "black boxes" where the implementation
  1292. details about how a module performs its work is kept hidden inside
  1293. the module, the user of a module only needs to know "what" the
  1294. module does and not "how".
  1295.  
  1296. Pascal supports two kinds of modules, "functions" and "procedures".
  1297. The difference between functions and procedures is that functions
  1298. return a value to their callers and are used in expressions, while
  1299. procedures do not return a value to their callers and are used in
  1300. procedure statements. Since functions and procedures are so similar
  1301. the generic term subroutine will be used to refer to both.
  1302.  
  1303. The recommended way of passing information into and out of subroutines
  1304. is by use of parameters. Subroutines may have a list of formal parameters,
  1305. these formal parameters are used by the subroutine to access information
  1306. passed into it. When the subroutine is called the caller must supply
  1307. an actual parameter for each formal parameter in the subroutine. The
  1308. actual parameter is the information being passed into or out of the
  1309. subroutine.
  1310.  
  1311. Irie Pascal supports four kinds of parameters (value parameters,
  1312. variable parameters, function parameters, and procedure parameters).
  1313. Value parameters are passed by value (i.e. when the subroutine is called
  1314. the actual parameter is an expression, and the value of the expression
  1315. passed into the formal parameter). The subroutine can use the formal
  1316. parameter to access the value passed to it but any changes it makes
  1317. to the formal parameter will not affect the actual parameter.
  1318. Variable parameters are passed by reference (i.e. when the subroutine
  1319. is called the actual parameter is a variable, and a reference to this
  1320. variable is passed into the formal parameter). The subroutine can
  1321. use the formal parameter to access the variable (via the reference)
  1322. and any changes it makes to the formal parameter will immediately
  1323. affect the actual parameter.
  1324. Function parameters are references to functions (i.e. when the
  1325. subroutine is called the actual parameter is a function, and a
  1326. reference to this function is passed into the formal parameter).
  1327. The subroutine can use the formal parameter to call the function.
  1328. Procedure parameters are references to procedures (i.e. when the
  1329. subroutine is called the actual parameter is a procedure, and a
  1330. reference to this procedure is passed into the formal parameter).
  1331. The subroutine can use the formal parameter to call the procedure.
  1332.  
  1333. For example here is an example of a simple program with a procedure.
  1334.  
  1335.    program simple(output);
  1336.  
  1337.       procedure say (message : string);
  1338.       begin
  1339.      writeln(message)
  1340.       end;
  1341.  
  1342.    begin
  1343.       say('Hello world')
  1344.    end.
  1345.  
  1346. The program contains a procedure called "say" which takes a single
  1347. value parameter. When the procedure is called "say('Hello world')"
  1348. the actual parameter is the expression 'Hello world' which is passed
  1349. into the formal parameter "message". So "message" now has the value
  1350. 'Hello world'. When writeln is used the value of "message"
  1351. (i.e. 'Hello world')
  1352. is written to the standard output stream.
  1353.  
  1354. Irie Pascal supports recursive function and procedure calls (i.e.
  1355. Irie Pascal allows functions and procedures to call themselves
  1356. either directly or indirectly). For example a procedure A
  1357. can call itself or it can call another procedure say B which in turn
  1358. calls procedure A.
  1359.  
  1360. Functions and procedures must be declared before they can be called.
  1361. This creates a problem when you have functions or procedures that
  1362. call each other. For example suppose you have the program below.
  1363.  
  1364.    program test(output);
  1365.  
  1366.       procedure a(x : integer);
  1367.       begin
  1368.      writeln(x);
  1369.      b(x+1)
  1370.       end;
  1371.  
  1372.       procedure b(x : integer);
  1373.       begin
  1374.      writeln(x);
  1375.      a(x+1)
  1376.       end;
  1377.  
  1378.    begin
  1379.       a(1);
  1380.    end.
  1381.  
  1382. If you try to compile this program the compiler will complain about
  1383. the call to "procedure b" that occurs in "procedure a" because this call
  1384. occurs before "procedure b" is declared.
  1385. You can try to correct this problem by moving the declaration of
  1386. "procedure b" before the declaration of "procedure a" like so
  1387.  
  1388.    program test(output);
  1389.  
  1390.       procedure b(x : integer);
  1391.       begin
  1392.      writeln(x);
  1393.      a(x+1)
  1394.       end;
  1395.  
  1396.       procedure a(x : integer);
  1397.       begin
  1398.      writeln(x);
  1399.      b(x+1)
  1400.       end;
  1401.  
  1402.    begin
  1403.       a(1);
  1404.    end.
  1405.  
  1406. but then the compiler will complain about the call to "procedure a"
  1407. that occurs in "procedure b", because this call now occurs before
  1408. "procedure a" is declared.
  1409.  
  1410. The "forward" directive can be used to solve this kind of problem as
  1411. illustrated by the program below:
  1412.  
  1413. program test(output);
  1414.  
  1415.    procedure b(x : integer); forward;
  1416.  
  1417.    procedure a(x : integer);
  1418.    begin
  1419.       writeln(x);
  1420.       b(x+1)
  1421.    end;
  1422.  
  1423.    procedure b;
  1424.    begin
  1425.       writeln(x);
  1426.       a(x+1)
  1427.    end;
  1428.  
  1429. begin
  1430.    a(1);
  1431. end.
  1432.  
  1433. You will notice that there are two declarations for procedure b.
  1434.  
  1435. The first declaration is called a forward declaration and includes
  1436. the name of the procedure and the formal parameter list
  1437. ("x:integer" in this case) and the directive "forward", but does not
  1438. include the procedure block.
  1439. The second declaration includes the name of the procedure and the
  1440. procedure block but does not include the formal parameter list.
  1441.  
  1442. The syntax for function and procedure declarations is given below:
  1443.  
  1444.    function-declaration =
  1445.        function-heading ';' directive |
  1446.        function-identification ';' function-block |
  1447.        function-heading ';' function-block
  1448.  
  1449.    procedure-declaration =
  1450.        procedure-heading ';' directive |
  1451.        procedure-identification ';' procedure-block |
  1452.        procedure-heading ';' procedure-block
  1453.  
  1454.    procedure-heading = 'procedure' identifier [ formal-parameter-list ]
  1455.  
  1456.    procedure-identification = 'procedure' procedure-identifier
  1457.  
  1458.    procedure-identifier = identifier
  1459.  
  1460.    procedure-block = block
  1461.  
  1462.    function-heading =
  1463.     'function' identifier [ formal-parameter-list ] ':' result-type
  1464.  
  1465.    function-identification = 'function' function-identifier
  1466.  
  1467.    function-identifier = identifier
  1468.  
  1469.    procedure-block = block
  1470.  
  1471.    function-block = block
  1472.  
  1473.    formal-parameter-list =
  1474.     '(' formal-parameter-section { ';' formal-parameter-section } ')'
  1475.  
  1476.    formal-parameter-section = value-parameter-specification |
  1477.                   variable-parameter-specification |
  1478.                   procedure-parameter-specification |
  1479.                   function-parameter-specification
  1480.  
  1481.    value-parameter-specification = identifier-list ':' type-identifier
  1482.  
  1483.    variable-parameter-specification =
  1484.          'var' identifier-list ':' type-identifier
  1485.  
  1486.    procedure-parameter-specification = procedure-heading
  1487.  
  1488.    function-parameter-specification = function-heading
  1489.  
  1490.    directive = 'forward'
  1491.  
  1492.    result-type = type-identifier
  1493.  
  1494. ----------------------
  1495. 7.1 Built-in Functions
  1496. ----------------------
  1497. Irie Pascal supports the following built-in functions.
  1498.  
  1499. ---------
  1500. 7.1.1 abs
  1501. ---------
  1502. Purpose: Returns the absolute value of its input.
  1503. Syntax:
  1504.    abs-call = 'abs' '(' num ')'
  1505.  
  1506.    num = integer-expression | real-expression
  1507.  
  1508. Standard Pascal: Yes
  1509. Example:
  1510.    abs(-10) is equal to 10
  1511. Notes:
  1512. The type of the value returned by this function is always the
  1513. same as the type of its input.
  1514.  
  1515. ------------
  1516. 7.1.2 arctan
  1517. ------------
  1518. Purpose: Returns the arctangent of its input
  1519. Syntax:
  1520.    arctan-call = 'arctan' '(' num ')'
  1521.  
  1522.    num = integer-expression | real-expression
  1523.  
  1524. Standard Pascal: Yes
  1525. Notes:
  1526. The type of the value returned by this function is always real.
  1527.  
  1528. ---------
  1529. 7.1.3 chr
  1530. ---------
  1531. Purpose: Returns the character whose ordinal value is equal to its input.
  1532. Syntax:
  1533.    chr-call = 'chr' '(' num ')'
  1534.  
  1535.    num = integer-expression
  1536.  
  1537. Standard Pascal: Yes
  1538. Notes:
  1539.  
  1540. ------------
  1541. 7.1.4 concat
  1542. ------------
  1543. Purpose: Returns a string formed by concatenating its input.
  1544. Syntax:
  1545.      concat-call = 'concat' '(' s { ',' s } ')'
  1546.  
  1547.      s = character-expression | string-expression
  1548.  
  1549. Standard Pascal: No
  1550. Notes:
  1551. For example you could do something like
  1552.    message := concat('Hello', ' ', 'world', '!');
  1553. to make message equal to 'Hello world!'
  1554. You can also concatenate strings and characters using the "+"
  1555. operator like
  1556.    message := 'Hello' + ' ' + 'world' + '!';
  1557.  
  1558. ----------
  1559. 7.1.5 copy
  1560. ----------
  1561. Purpose: Returns a string formed by copying from an input string starting
  1562.      from a specified position.
  1563. Syntax:
  1564.        copy-call = 'copy' '(' s ',' p [ ',' n ')'
  1565.  
  1566.        s = character-expression | string-expression
  1567.  
  1568.        p = integer-expression
  1569.  
  1570.        n = integer-expression
  1571.  
  1572. Standard Pascal: No
  1573. Notes:
  1574.    "s" is the source of characters
  1575.    "p" specifies the position from which to start copying characters
  1576.    "n" specifies the number of characters to copy. If "n" is omitted or is
  1577.        greater than the number of characters in "s" from "p" to the end,
  1578.        then all characters in "s" starting from "p" to the end are copied.
  1579.  
  1580. For example
  1581.     copy('Testing...', 5, 2)    is equal to 'in'
  1582. and
  1583.     copy('Testing...', 7)       is equal to 'g...'
  1584. and
  1585.     copy('Testing...', 1, 1000) is equal to 'Testing...'
  1586.  
  1587. ---------
  1588. 7.1.6 cos
  1589. ---------
  1590. Purpose: Returns the cosine of its input (expressed in radians).
  1591. Syntax:
  1592.    cos-call = 'cos' '(' num ')'
  1593.  
  1594.    num = integer-expression | real-expression
  1595. Standard Pascal: Yes
  1596. Notes:
  1597. The type of the value returned by this function is always real.
  1598.  
  1599. ----------
  1600. 7.1.7 cosh
  1601. ----------
  1602. Purpose: Returns the hyperbolic cosine of its input.
  1603. Syntax:
  1604.    cosh-call = 'cosh' '(' num ')'
  1605.  
  1606.    num = integer-expression | real-expression
  1607. Standard Pascal: No
  1608. Notes:
  1609. The type of the value returned by this function is always real.
  1610.  
  1611. ---------
  1612. 7.1.8 eof
  1613. ---------
  1614. Purpose: Returns "true" or "false" depending on whether its input
  1615.      (which is a file variable) is at end-of-file.
  1616. Syntax:
  1617.    eof-call = 'eof' [ '(' f ')' ]
  1618.  
  1619.    f = file-variable
  1620.  
  1621.    If "f" is omitted then the built-in file variable "input" shall be used as
  1622.      input to this function.
  1623. Standard Pascal: Yes
  1624. Notes:
  1625.  
  1626. ----------
  1627. 7.1.9 eoln
  1628. ----------
  1629. Purpose: Returns "true" or "false" depending on whether its input
  1630.      (which is a file variable) is at end-of-line.
  1631. Syntax:
  1632.    eoln-call = 'eoln' [ '(' t ')' ]
  1633.  
  1634.    t = text-file-variable
  1635.  
  1636.    If "t" is omitted then the built-in text file variable "input" shall be
  1637.      used as input to this function.
  1638. Standard Pascal: Yes
  1639. Notes:
  1640.  
  1641. ----------
  1642. 7.1.10 exp
  1643. ----------
  1644. Purpose: Returns the value of "e" raised to the power of its input.
  1645. Syntax:
  1646.    exp-call = 'exp' '(' num ')'
  1647.  
  1648.    num = integer-expression | real-expression
  1649. Standard Pascal: Yes
  1650. Notes:
  1651. The type of the value returned by this function is always real.
  1652.  
  1653. --------------
  1654. 7.1.11 fexpand
  1655. --------------
  1656. Purpose: Returns the full pathname of its input (which is a filename).
  1657. Syntax:
  1658.    fexpand-call = 'fexpand' '(' s ')'
  1659.  
  1660.    s = character-expression | string-expression
  1661.  
  1662. Standard Pascal: No
  1663. Notes:
  1664.  
  1665. --------------
  1666. 7.1.12 filepos
  1667. --------------
  1668. Purpose: Returns the value of the file position indicator of a file.
  1669. Syntax:
  1670.    filepos-call = 'filepos' '(' f ')'
  1671.  
  1672.    f = file-variable
  1673.  
  1674. Standard Pascal: No
  1675. Notes:
  1676. This function returns an integer value.
  1677. The file variable "f" must be open.
  1678. For a text file variable the value of the file position indicator may
  1679. not be equal to the number of characters read/written so far.
  1680. For a binary file the value of the file position indicator is equal to
  1681. the number of characters read/written so far.
  1682.  
  1683. ---------------
  1684. 7.1.13 filesize
  1685. ---------------
  1686. Purpose: Returns the size of a file.
  1687. Syntax:
  1688.    filesize-call = 'filesize' '(' f ')'
  1689.  
  1690.    f = file-variable
  1691.  
  1692. Standard Pascal: No
  1693. Notes:
  1694. This function returns an integer value.
  1695. The file variable "f" must be open.
  1696.  
  1697. -----------
  1698. 7.1.14 frac
  1699. -----------
  1700. Purpose: Returns the fractional part of a real expression.
  1701. Syntax:
  1702.    frac-call = 'frac' '(' r ')'
  1703.  
  1704.    r = real-expression
  1705.  
  1706. Standard Pascal: No
  1707. Notes:
  1708. For example frac(7.234) is equal to 0.234
  1709. The type of the value returned by this function is always real.
  1710.  
  1711. -------------
  1712. 7.1.15 getenv
  1713. -------------
  1714. Purpose: Returns the environment variable specified by its input.
  1715. Syntax:
  1716.    genenv-call = 'getenv' '(' s ')'
  1717.  
  1718.    s = character-expression | string-expression
  1719.  
  1720. Standard Pascal: No
  1721. Notes:
  1722. If a string matching "s" can not be found in the environment list then an
  1723. empty string is returned.
  1724.  
  1725. ----------
  1726. 7.1.16 hex
  1727. ----------
  1728. Purpose: Returns the hexadecimal representation of its input as a string.
  1729. Syntax:
  1730.     hex-call = 'hex' '(' i ')'
  1731.  
  1732.     i = integer-expression
  1733.  
  1734. Standard Pascal: No
  1735. Notes:
  1736. For example hex(16) is equal to '10'.
  1737.  
  1738. ----------
  1739. 7.1.17 int
  1740. ----------
  1741. Purpose: Returns the integer part of a real expression.
  1742. Syntax:
  1743.    int-call = 'int' '(' r ')'
  1744.  
  1745.    r = real-expression
  1746. Standard Pascal: No
  1747. Notes:
  1748. For example int(7.234) is equal to 7.0
  1749. The type of the value returned by this function is always real.
  1750.  
  1751. ---------------
  1752. 7.1.18 ioresult
  1753. ---------------
  1754. Purpose: Returns the error code of the last input/output operation.
  1755. Syntax:
  1756.    ioresult-call = 'ioresult'
  1757. Standard Pascal: No
  1758. Notes:
  1759. By default (when I/O checking is enabled) your program automatically
  1760. checks for errors after each I/O operation and terminates with an error
  1761. message if any errors are detected. If you do not want this default
  1762. behavior you can disable I/O checking (either globally using the "i"
  1763. compiler option or locally using the "i" compiler directive) and call
  1764. this function to determine if any I/O errors occurred.
  1765. (See "Appendix F" of the "Irie Pascal Users Manual" for a list of the error
  1766. codes returned by this function.
  1767. This function resets the error code to zero after it is called, so if you
  1768. call this function twice after an I/O operation then the second call
  1769. will always return 0. If you need to refer to the error code more than once
  1770. you can save the error code into a variable.
  1771. For example:
  1772.    errcode := IOResult;
  1773.    if errcode <> 0 then
  1774.        case errcode of
  1775.     1: writeln('Error erasing file');
  1776.     2: writeln('Error renaming file');
  1777.     3: writeln('File is undefined')
  1778.        end
  1779.  
  1780. --------------
  1781. 7.1.19 isalpha
  1782. --------------
  1783. Purpose: Returns "true" or "false" depending on whether its input
  1784.      is a alphabetic character.
  1785. Syntax:
  1786.    isalpha-call = 'isalpha' '(' c ')'
  1787.  
  1788.    c = character-expression
  1789.  
  1790. Standard Pascal: No
  1791. Notes:
  1792.  
  1793. -----------------
  1794. 7.1.20 isalphanum
  1795. -----------------
  1796. Purpose: Returns "true" or "false" depending on whether its input
  1797.      is a alphanumeric character.
  1798. Syntax:
  1799.    isalphanum-call = 'isalphanum' '(' c ')'
  1800.  
  1801.    c = character-expression
  1802.  
  1803. Standard Pascal: No
  1804. Notes:
  1805.  
  1806. --------------
  1807. 7.1.21 isdigit
  1808. --------------
  1809. Purpose: Returns "true" or "false" depending on whether its input
  1810.      is a digit character.
  1811. Syntax:
  1812.    isdigit-call = 'isdigit' '(' c ')'
  1813.  
  1814.    c = character-expression
  1815.  
  1816. Standard Pascal: No
  1817. Notes:
  1818.  
  1819. --------------
  1820. 7.1.22 islower
  1821. --------------
  1822. Purpose: Returns "true" or "false" depending on whether its input
  1823.      is a lower case letter.
  1824. Syntax:
  1825.    islower-call = 'islower' '(' c ')'
  1826.  
  1827.    c = character-expression
  1828.  
  1829. Standard Pascal: No
  1830. Notes:
  1831.  
  1832. --------------
  1833. 7.1.23 isprint
  1834. --------------
  1835. Purpose: Returns "true" or "false" depending on whether its input
  1836.      is a printable character.
  1837. Syntax:
  1838.    isprint-call = 'isprint' '(' c ')'
  1839.  
  1840.    c = character-expression
  1841.  
  1842. Standard Pascal: No
  1843. Notes:
  1844.  
  1845. --------------
  1846. 7.1.24 isspace
  1847. --------------
  1848. Purpose: Returns "true" or "false" depending on whether its input
  1849.      is a white space character.
  1850. Syntax:
  1851.    isspace-call = 'isspace' '(' c ')'
  1852.  
  1853.    c = character-expression
  1854.  
  1855. Standard Pascal: No
  1856. Notes:
  1857.  
  1858. --------------
  1859. 7.1.25 isupper
  1860. --------------
  1861. Purpose: Returns "true" or "false" depending on whether its input
  1862.      is an upper case letter.
  1863. Syntax:
  1864.    isupper-call = 'isupper' '(' c ')'
  1865.  
  1866.    c = character-expression
  1867.  
  1868. Standard Pascal: No
  1869. Notes:
  1870.  
  1871. ---------------
  1872. 7.1.26 isxdigit
  1873. ---------------
  1874. Purpose: Returns "true" or "false" depending on whether its input
  1875.      is a hexadecimal digit character.
  1876. Syntax:
  1877.    isxdigit-call = 'isxdigit' '(' c ')'
  1878.  
  1879.    c = character-expression
  1880.  
  1881. Standard Pascal: No
  1882. Notes:
  1883.  
  1884. -------------
  1885. 7.1.27 length
  1886. -------------
  1887. Purpose: Returns the length of its input.
  1888. Syntax:
  1889.    length-call = 'length' '(' v ')'
  1890.  
  1891.    v = list-variable | string-variable
  1892.  
  1893. Standard Pascal: No
  1894. Notes:
  1895.  
  1896. ---------
  1897. 7.1.28 ln
  1898. ---------
  1899. Purpose: Returns the natural logarithm of its input.
  1900. Syntax:
  1901.    ln-call = 'ln' '(' num ')'
  1902.  
  1903.    num = integer-expression | real-expression
  1904. Standard Pascal: Yes
  1905. Notes:
  1906. The type of the value returned by this function is always real.
  1907.  
  1908. ----------
  1909. 7.1.29 log
  1910. ----------
  1911. Purpose: Returns the logarithm to the base 10 of its input.
  1912. Syntax:
  1913.    log-call = 'log' '(' num ')'
  1914.  
  1915.    num = integer-expression | real-expression
  1916. Standard Pascal: Yes
  1917. Notes:
  1918. The type of the value returned by this function is always real.
  1919.  
  1920. -------------
  1921. 7.1.30 locase
  1922. -------------
  1923. Purpose: Returns the lowercase letter corresponding to its input.
  1924.      If there is no lowercase letter corresponding to its input
  1925.      then its input is returned.
  1926. Syntax:
  1927.    locase-call = 'locase' '(' c ')'
  1928.  
  1929.    c = character-expression
  1930. Standard Pascal: No
  1931. Notes:
  1932.  
  1933. ----------------
  1934. 7.1.31 lowercase
  1935. ----------------
  1936. Purpose: Returns a string formed by converting all lower case characters
  1937.      in its input to upper case characters and leaving all other
  1938.      characters unchanged.
  1939. Syntax:
  1940.    lowercase-call = 'lowercase' '(' s ')'
  1941.  
  1942.    s = string-expression
  1943. Standard Pascal: No
  1944. Notes:
  1945.  
  1946. ----------
  1947. 7.1.32 odd
  1948. ----------
  1949. Purpose: Returns "true" or "false" depending on whether its input
  1950.      is an odd number.
  1951. Syntax:
  1952.    odd-call = 'odd' '(' i ')'
  1953.  
  1954.    i = integer-expression
  1955. Standard Pascal: Yes
  1956. Notes:
  1957.  
  1958. ----------
  1959. 7.1.33 ord
  1960. ----------
  1961. Purpose: Returns the ordinal value of its input.
  1962. Syntax:
  1963.    ord-call = 'ord' '(' o ')'
  1964.  
  1965.    o = ordinal-expression
  1966.  
  1967. Standard Pascal: Yes
  1968. Notes:
  1969. The type of the value returned by this function is always integer.
  1970.  
  1971. -----------------
  1972. 7.1.34 paramcount
  1973. -----------------
  1974. Purpose: Returns the number of arguments passed to the program.
  1975. Syntax:
  1976.    paramcount-call = 'paramcount'
  1977. Standard Pascal: No
  1978. Notes:
  1979. For example the following is the sample program "args.pas".
  1980.  
  1981.    program args(output);
  1982.    begin
  1983.       writeln('Number of program arguments =', paramcount)
  1984.    end.
  1985.  
  1986. If you compile it and run it as follows
  1987.     ipc args
  1988.     ivm args this is a test
  1989. then the output would be
  1990.     Number of program arguments = 4
  1991.  
  1992. ---------------
  1993. 7.1.35 paramstr
  1994. ---------------
  1995. Purpose: Returns the ith program argument string where i is its input.
  1996. Syntax:
  1997.    paramstr-cal = 'paramstr' '(' i ')'
  1998.  
  1999.    i = integer-expression
  2000. Standard Pascal: No
  2001. Notes:
  2002. If there is no ith program argument an empty string is returned.
  2003.  
  2004. ---------
  2005. 7.1.36 pi
  2006. ---------
  2007. Purpose: Returns the value of the mathematical constant pi.
  2008. Syntax:
  2009.    pi-call = 'pi'
  2010. Standard Pascal: No
  2011. Notes:
  2012.  
  2013. ---------------
  2014. 7.1.37 platform
  2015. ---------------
  2016. Purpose: Returns an integer indicating the platform the program is
  2017.      running on.
  2018. Syntax:
  2019.    platform-call = 'platform'
  2020. Standard Pascal: No
  2021. Notes:
  2022. As an extension Irie Pascal supports four integer constants "platform_dos",
  2023. "platform_os2", "platform_win32", and "platform_linux" which can be
  2024. compared with the value returned by this function.
  2025.  
  2026. ----------
  2027. 7.1.38 pos
  2028. ----------
  2029. Purpose: Searches for one string in another.
  2030. Syntax:
  2031.    pos-call = 'pos' '(' needle ',' haystack [ ',' start ')'
  2032.  
  2033.    needle = character-expression | string-expression
  2034.  
  2035.    haystack = character-expression | string-expression
  2036.  
  2037.    start = integer-expression
  2038.  
  2039. Standard Pascal: No
  2040. Notes:
  2041. This functions searches "haystack" starting at position "start"
  2042. for "needle" and returns 0 if "needle" is not found or returns the
  2043. position of "needle" in "haystack". If "start" is omitted then the search
  2044. begins at position 1. If "start" is greater than the length of "haystack"
  2045. then 0 is returned.
  2046. For example
  2047.    pos('o', 'Hello world')    is equal to 5
  2048.    pos('o', 'Hello world', 1) is equal to 5
  2049.    pos('o', 'Hello world', 6) is equal to 8
  2050.    pos('o', 'Hello world', 256) is equal to 0
  2051.  
  2052. -----------
  2053. 7.1.39 pred
  2054. -----------
  2055. Purpose: Returns an ordinal value that is one less than its input.
  2056. Syntax:
  2057.    pred-call = 'pred' '(' o ')'
  2058.  
  2059.    o = ordinal-expression
  2060.  
  2061. Standard Pascal: Yes
  2062. Notes:
  2063. The type of the value returned by this function is always the same
  2064. as the type of its input.
  2065.  
  2066. -------------
  2067. 7.1.40 random
  2068. -------------
  2069. Purpose: Returns a pseudo-random number.
  2070. Syntax:
  2071.    random-call = 'random' [ '(' i ')' ]
  2072.  
  2073.    i = integer-expression
  2074.  
  2075. Standard Pascal: No
  2076. Notes:
  2077. If "i" is not specified then "random" returns a real value between
  2078. 0 and 1.
  2079. If "i" is specified then "random" returns an integer value
  2080. between 1 and "i"-1.
  2081. See also "7.2.31 randomize".
  2082.  
  2083. --------------
  2084. 7.1.41 reverse
  2085. --------------
  2086. Purpose: Returns a string created by reversing the characters in its input.
  2087. Syntax:
  2088.    reverse-call = 'reverse' '(' s ')'
  2089.  
  2090.    s = character-expression | string-expression
  2091.  
  2092. Standard Pascal: No
  2093. Notes:
  2094. For example
  2095.     reverse('Hello')    is equal to 'olleH'
  2096.  
  2097. ------------
  2098. 7.1.42 round
  2099. ------------
  2100. Purpose: Returns the integer value closes to its input.
  2101. Syntax:
  2102.    round-call = 'round' '(' r ')'
  2103.  
  2104.    r = real-expression
  2105.  
  2106. Standard Pascal: Yes
  2107. Notes:
  2108. For example round(7.234) is equal to 7.
  2109. The type of the value returned by this function is always integer.
  2110.  
  2111. ----------
  2112. 7.1.43 sin
  2113. ----------
  2114. Purpose: Returns the sine of its input (expressed in radians).
  2115. Syntax:
  2116.    sin-call = 'sin' '(' num ')'
  2117.  
  2118.    num = integer-expression | real-expression
  2119.  
  2120. Standard Pascal: Yes
  2121. Notes:
  2122. The type of the value returned by this function is always real.
  2123.  
  2124. -----------
  2125. 7.1.44 sinh
  2126. -----------
  2127. Purpose: Returns the hyperbolic sine of its input.
  2128. Syntax:
  2129.    sinh-call = 'sinh' '(' num ')'
  2130.  
  2131.    num = integer-expression | real-expression
  2132.  
  2133. Standard Pascal: No
  2134. Notes:
  2135. The type of the value returned by this function is always real.
  2136.  
  2137. ----------
  2138. 7.1.45 sqr
  2139. ----------
  2140. Purpose: Returns the square of its input
  2141. Syntax:
  2142.    sqr-call = 'sqr' '(' num ')'
  2143.  
  2144.    num = integer-expression | real-expression
  2145.  
  2146. Standard Pascal: Yes
  2147. Notes:
  2148. The type of the value returned by this function is always the same as
  2149. the type of its input.
  2150.  
  2151. -----------
  2152. 7.1.46 sqrt
  2153. -----------
  2154. Purpose: Returns the square-root of its input
  2155. Syntax:
  2156.    sqrt-call = 'sqrt' '(' num ')'
  2157.  
  2158.    num = integer-expression | real-expression
  2159.  
  2160. Standard Pascal: Yes
  2161. Notes:
  2162. The type of the value returned by this function is always real.
  2163.  
  2164. -----------
  2165. 7.1.47 succ
  2166. -----------
  2167. Purpose: Returns an ordinal value that is one more than its input.
  2168. Syntax:
  2169.    succ-call = 'succ' '(' o ')'
  2170.  
  2171.    o = ordinal-expression
  2172.  
  2173. Standard Pascal: Yes
  2174. Notes:
  2175. The type of the value returned by this function is always the same
  2176. as the type of its input.
  2177.  
  2178. -----------
  2179. 7.1.48 swap
  2180. -----------
  2181. Purpose: Returns an integer value calculated by reversing the byte
  2182.      ordering of its input.
  2183. Syntax:
  2184.    swap-call = 'swap' '(' i ')'
  2185.  
  2186.    i = integer-expression
  2187.  
  2188. Standard Pascal: No
  2189. Notes:
  2190. For example assuming 32 bit little endian integers then 256 is stored in
  2191. four bytes as follows:
  2192.  
  2193.    0 0 1 0
  2194.  
  2195. So swap(256) results in the following integer:
  2196.  
  2197.    0 1 0 0
  2198.  
  2199. which is equal to 65536
  2200.  
  2201. -------------
  2202. 7.1.49 system
  2203. -------------
  2204. Purpose: Passes its input to the command processor, which will attempt to
  2205. execute it as a command.
  2206. Syntax:
  2207.    system-call = 'system' '(' s ')'
  2208.  
  2209.    s = string-expression
  2210.  
  2211. Standard Pascal: No
  2212. Notes:
  2213. If there is an error then "system" returns a non-zero value indicating
  2214. the kind of error.
  2215. If there is no error then "system" returns zero.
  2216.  
  2217. See also "7.2.11 Exec".
  2218.  
  2219. For example the sample program "batch.pas" below is a very primitive
  2220. batch processor. It sends each line in the input file to the command
  2221. processor to be executed.
  2222.  
  2223.    program batch(f, output);
  2224.    var
  2225.       f : text;
  2226.       s : string;
  2227.       err : integer;
  2228.    begin
  2229.       reset(f);    (* open input file or standard input file *)
  2230.       while not eof(f) do
  2231.      begin
  2232.         readln(f, s);
  2233.         writeln('Executing ', s);
  2234.         err := system(s);      (* Pass 's' to the command processor *)
  2235.         writeln('Error code is ', err)
  2236.      end
  2237.    end.
  2238.  
  2239. ----------
  2240. 7.1.50 tan
  2241. ----------
  2242. Purpose: Returns the tangent of its input (expressed in radians).
  2243. Syntax:
  2244.    tan-call = 'tan' '(' num ')'
  2245.  
  2246.    num = integer-expression | real-expression
  2247.  
  2248. Standard Pascal: No
  2249. Notes:
  2250. The type of the value returned by this function is always real.
  2251.  
  2252. -----------
  2253. 7.1.51 tanh
  2254. -----------
  2255. Purpose: Returns the hyperbolic tangent of its input.
  2256. Syntax:
  2257.    tanh-call = 'tanh' '(' num ')'
  2258.  
  2259.    num = integer-expression | real-expression
  2260.  
  2261. Standard Pascal: No
  2262. Notes:
  2263. The type of the value returned by this function is always real.
  2264.  
  2265. -----------
  2266. 7.1.52 trim
  2267. -----------
  2268. Purpose: Returns a string created by removing all leading and trailing
  2269.      spaces from its input.
  2270. Syntax:
  2271.    trim-call = 'trim' '(' s ')'
  2272.  
  2273.    s = string-expression
  2274.  
  2275. Standard Pascal: No
  2276. Notes:
  2277. For example
  2278.     trim(' hello ') is equal to 'hello'
  2279.  
  2280. ------------
  2281. 7.1.53 trunc
  2282. ------------
  2283. Purpose: Returns an integer value formed by removing the fractional
  2284.      part of its input.
  2285. Syntax:
  2286.    trunc-call = 'trunc' '(' r ')'
  2287.  
  2288.    r = real-expression
  2289.  
  2290. Standard Pascal: Yes
  2291. Notes:
  2292. For example trunc(7.234) is equal to 7.
  2293. The type of the value returned by this function is always integer.
  2294.  
  2295. -------------
  2296. 7.1.54 upcase
  2297. -------------
  2298. Purpose: Returns the uppercase letter corresponding to its input.
  2299.      If there is no uppercase letter corresponding to its input
  2300.      then its input is returned.
  2301. Syntax:
  2302.    upcase-call = 'upcase' '(' c ')'
  2303.  
  2304.    c = character-expression
  2305.  
  2306. Standard Pascal: No
  2307. Notes:
  2308.  
  2309. ----------------
  2310. 7.1.55 uppercase
  2311. ----------------
  2312. Purpose: Returns a string formed by converting all upper case characters
  2313.      in its input to lower case characters and leaving all other
  2314.      characters unchanged.
  2315. Syntax:
  2316.    uppercase-call = 'uppercase' '(' s ')'
  2317.  
  2318.    s = string-expression
  2319.  
  2320. Standard Pascal: No
  2321. Notes:
  2322.  
  2323. -----------------------
  2324. 7.2 Built-in Procedures
  2325. -----------------------
  2326. Irie Pascal supports the following built-in procedures.
  2327.  
  2328. ------------
  2329. 7.2.1 append
  2330. ------------
  2331. Purpose: Opens a file for writing at the end of the file, and associates
  2332.      a file variable with the opened file.
  2333. Syntax:
  2334.    append-call = 'append' '(' f [',' s ] ')'
  2335.  
  2336.    f = file-variable
  2337.  
  2338.    s = filename
  2339.  
  2340. Standard Pascal: No
  2341. Notes:
  2342. If the file does not exist it is created. If the file exists its contents
  2343. are preserved. In either case all writes occur at the end of the file.
  2344.  
  2345. If a filename ("s") is specified then the filename is assigned to the
  2346. file variable before the file is opened (the file must be closed).
  2347. After the file is opened all writes will occur at the end of the file
  2348. regardless of calls to the built-in seek procedure (See "7.2.40 rewrite",
  2349. "7.2.3 assign", "7.2.38 reset", and "7.2.42 seek").
  2350.  
  2351. ------------
  2352. 7.2.2 assert
  2353. ------------
  2354. Purpose: This procedure is based on the C language macro of the same name.
  2355.      The assert procedure can be enabled/disabled using the -A compiler
  2356.      option. When enabled this procedure evaluates its input, which is
  2357.      a boolean expression and aborts the program if the expression
  2358.      evaluates to false. If the expression evaluates to true nothing
  2359.      happens.
  2360.      The idea behind this procedure is that you use it during debugging
  2361.      to verify that the variables in your program have the values you
  2362.      expect, and after your program is debugged you don't have to
  2363.      search your program and remove the calls to this procedure, instead
  2364.      you just disable this procedure using a compiler option.
  2365.      A common mistake in using this procedure is to test normal error
  2366.      conditions (such as out of memory or invalid user input).
  2367. Syntax:
  2368.    assert-call = 'assert' '(' b ')'
  2369.  
  2370.    b = boolean-expression
  2371.  
  2372. Standard Pascal: No
  2373. Notes:
  2374.  
  2375. ------------
  2376. 7.2.3 assign
  2377. ------------
  2378. Purpose: Assigns a name to a file variable.
  2379. Syntax:
  2380.    assign-call = 'assign' '(' f ',' name ')'
  2381.  
  2382.    f = file-variable
  2383.  
  2384.    name = character-expression | string-expression
  2385.  
  2386. Standard Pascal: No
  2387. Notes:
  2388. The file variable "f" must be closed.
  2389.  
  2390. For example to open a file named 'README.TXT' for reading use
  2391.     assign(f, 'README.TXT');
  2392.     reset(f);
  2393.  
  2394. You can't use this function to rename a file, use the "rename" procedure
  2395. if you want to do that.
  2396.  
  2397. -----------
  2398. 7.2.4 chdir
  2399. -----------
  2400. Purpose: Changes the current directory.
  2401. Syntax:
  2402.   chdir-call = 'chdir' '(' name ')'
  2403.  
  2404.   name = character-expression | string-expression
  2405.  
  2406. Standard Pascal: No
  2407. Notes:
  2408. "name" specifies the name of the directory that is to be the new
  2409. current directory.
  2410.  
  2411. -----------
  2412. 7.2.5 close
  2413. -----------
  2414. Purpose: Flushes and then closes a file.
  2415. Syntax:
  2416.    close-call = 'close' '(' f ')'
  2417.  
  2418.    f = file-variable
  2419.  
  2420. Standard Pascal: No
  2421. Notes:
  2422.  
  2423. --------------
  2424. 7.2.6 closedir
  2425. --------------
  2426. Purpose: Closes a directory.
  2427. Syntax:
  2428.    closedir-call = 'closedir' '(' d ')'
  2429.  
  2430.    d = directory-variable
  2431.  
  2432. Standard Pascal: No
  2433. Notes:
  2434. Irie Pascal allows you to open, read, rewind, and close directories
  2435. (See also "7.2.27 opendir", "7.2.35 readdir", "7.2.39 rewinddir").
  2436.  
  2437. ---------
  2438. 7.2.7 dec
  2439. ---------
  2440. Purpose: Decrements an ordinal variable by a specified amount or by one.
  2441. Syntax:
  2442.    dec-call = 'dec' '(' o [',' i ] ')'
  2443.  
  2444.    o = ordinal-variable
  2445.  
  2446.    i = integer-expression
  2447.  
  2448. Standard Pascal: No
  2449. Notes:
  2450. If "i" is omitted then "o" is decremented by one.
  2451. Using this function is slightly more efficient than using
  2452.     o := o - i;
  2453.  
  2454. ------------
  2455. 7.2.8 delete
  2456. ------------
  2457. Purpose: Deletes components from a list or a string.
  2458. Syntax:
  2459.  
  2460.    delete-call = delete-list | delete-string
  2461.  
  2462.    delete-list = 'delete' '(' l ',' start [',' count ] ')'
  2463.  
  2464.    delete-string = 'delete' '(' s ',' start [ ',' count ] ')'
  2465.  
  2466.    l = list-variable
  2467.  
  2468.    start = integer-expression
  2469.  
  2470.    count = integer-expression
  2471.  
  2472.    s = string-variable
  2473.  
  2474. Standard Pascal: No
  2475. Notes:
  2476. "start" specifies the position in the list or string to start deleting from.
  2477. "count" specifies the number of components to delete. If "count" is omitted
  2478. then all components from "start" to the end are deleted.
  2479.  
  2480. -------------
  2481. 7.2.9 dispose
  2482. -------------
  2483. Purpose: Releases memory allocated using "new".
  2484. Syntax:
  2485.    dispose-call = dispose-pointer | dispose-list
  2486.  
  2487.    dispose-pointer = 'dispose' '(' p ')'
  2488.  
  2489.    dispose-list = 'dispose' '(' l ')'
  2490.  
  2491.    p = pointer-variable
  2492.  
  2493.    l = list-variable
  2494.  
  2495. Standard Pascal: Yes
  2496. Notes:
  2497. After the call to dispose the pointer variable or list variable is
  2498. undefined.
  2499.  
  2500. ------------
  2501. 7.2.10 erase
  2502. ------------
  2503. Purpose: Deletes a file.
  2504. Syntax:
  2505.    erase-call = 'erase' '(' f ')'
  2506.  
  2507.    f = file-variable
  2508.  
  2509. Standard Pascal: No
  2510. Notes:
  2511. The file must be closed and have a name associated with it.
  2512.  
  2513. -----------
  2514. 7.2.11 exec
  2515. -----------
  2516. Purpose: Executes a program.
  2517. Syntax:
  2518.    exec-call = 'exec' '(' p ',' 'a' ')'
  2519.  
  2520.    p = character-expression | string-expression
  2521.  
  2522.    a = character-expression | string-expression
  2523.  
  2524. Standard Pascal: No
  2525. Notes:
  2526. "p" specifies the program to execute.
  2527. "a" specifies the arguments (if any) to be passed to the program
  2528. (see also "7.1.49 system", "7.1.34 paramcount" and "7.1.35 paramstr").
  2529.  
  2530. The code returned by the program if any is stored in the built-in
  2531. variable "exitcode".
  2532.  
  2533. -----------
  2534. 7.2.12 exit
  2535. -----------
  2536. Purpose: Terminates the function/procedure/program in which it is used,
  2537.      and optionally returns a value.
  2538. Syntax:
  2539.    exit-call = 'exit' [ '(' e ')' ]
  2540.  
  2541.    e = expression
  2542.  
  2543. Standard Pascal: No
  2544. Notes:
  2545. "i" if specifies is the value to be returned by the function or program
  2546.  
  2547. If used in a function then "exit" terminates the function.
  2548. If used in a function named "f" then "exit(e)" is equivalent to
  2549.       f := e;
  2550.       exit
  2551. If used in a procedure then "exit" terminates the procedure.
  2552. If used in a procedure then "exit(x)" is an error since you can
  2553.     not return a value from a procedure.
  2554. If used not in a function or procedure but in the main program
  2555.   then "exit" terminates the program.
  2556. If used not in a function or procedure but in the main program
  2557.   then "exit(e)" is equivalent to:
  2558.       ExitCode := e;
  2559.       exit
  2560.       (i.e. the program is terminated with "e" as the exit code).
  2561.  
  2562. See also "7.2.21 halt".
  2563.  
  2564. ------------
  2565. 7.2.13 flush
  2566. ------------
  2567. Purpose: Flushes the a file's buffers (i.e. all data waiting to be written
  2568.      to the file is written).
  2569. Syntax:
  2570.    flush-call = 'flush' '(' f ')'
  2571.  
  2572.    f = file-variable
  2573.  
  2574. Standard Pascal: No
  2575. Notes:
  2576. The file associated with "f" must be open.
  2577.  
  2578. -------------
  2579. 7.2.14 fsplit
  2580. -------------
  2581. Purpose: Splits a filename into its component parts.
  2582. Syntax:
  2583.    fsplit-call = fsplit '(' s ',' [ d ] ',' [ n ] ',' [ e ] ')'
  2584.  
  2585.    s = character-expression | string-expression
  2586.  
  2587.    d = string-variable
  2588.  
  2589.    n = string-variable
  2590.  
  2591.    e = string-variable
  2592.  
  2593. Standard Pascal: No
  2594. Notes:
  2595. "s" specifies the filename to be split.
  2596. "d" specifies a variable to store the directory part of the filename.
  2597. "n" specifies a variable to store the name part of the filename (minus
  2598.     the extension.
  2599. "e" specifies a variable to store the extension part of the filename.
  2600.  
  2601. Although "d", "n", and "e" are optional at least one must be specified.
  2602.  
  2603. ----------
  2604. 7.2.15 get
  2605. ----------
  2606. Purpose: Reads the next component in a file into the file variable's buffer.
  2607. Syntax:
  2608.    get-call = 'get' '(' f ')'
  2609.  
  2610.    f = file-variable
  2611.  
  2612. Standard Pascal: Yes
  2613. Notes:
  2614.  
  2615. --------------
  2616. 7.2.16 getdate
  2617. --------------
  2618. Purpose: Retrieves the current system date.
  2619. Syntax:
  2620.    getdate-call = 'getdate' '(' year ',' month ',' day ',' day_of_week ')'
  2621.  
  2622.    year = integer-variable
  2623.  
  2624.    month = integer-variable
  2625.  
  2626.    day = integer-variable
  2627.  
  2628.    day_of_week = integer-variable
  2629.  
  2630. Standard Pascal: No
  2631. Notes:
  2632. "year" stores the current year
  2633. "month" stores the current month (1 to 12).
  2634. "day" stores the current day of the month (1 to 31)
  2635. "day_of_week" stores the current day of the week
  2636.      (0 to 6 counting from Sunday).
  2637.  
  2638. Suppose the current system date is Wednesday September 30, 1998 then after
  2639.     GetDate(year, month, day, day_of_week)
  2640.     year = 1998
  2641.     month = 9
  2642.     day = 30
  2643.     day_of_week = 3
  2644.  
  2645. ------------------
  2646. 7.2.17 getfiledate
  2647. ------------------
  2648. Purpose: Returns the date a file was last modified.
  2649. Syntax:
  2650.    getfiledate-call = 'getfiledate' '(' name ',' year ',' month ',' day ')'
  2651.  
  2652.    name = character-expression | string-expression
  2653.  
  2654.    year = integer-variable
  2655.  
  2656.    month = integer-variable
  2657.  
  2658.    day = integer-variable
  2659.  
  2660. Standard Pascal: No
  2661. Notes:
  2662. "name" is the name of the file to test.
  2663. "year" stores the year the file was last modified.
  2664. "month" stores the month the file was last modified (1 to 12)
  2665. "day" stores the day of the month the file was last modified (1 to 31)
  2666.  
  2667. ------------------
  2668. 7.2.18 getfilemode
  2669. ------------------
  2670. Purpose: Gets a file's mode.
  2671. Syntax:
  2672.    getfilemode-call = 'getfilemode' '(' name ',' mode ')'
  2673.  
  2674.    name = character-expression | string-expression
  2675.  
  2676.    mode = integer-variable
  2677.  
  2678. Standard Pascal: No
  2679. Notes:
  2680. "name" is the name of the file to test.
  2681. "mode" stores the file mode.
  2682.  
  2683. After the call "mode" can be AND'd with the following built-in constants
  2684. to determine information about the file:
  2685. The constants "usr_r", "usr_w", and "usr_x" can be AND'd with "mode"
  2686. to determine the user read, write, and execute permissions for the file.
  2687. The constants "grp_r", "grp_w", and "grp_x" can be AND'd with "mode"
  2688. to determine the group read, write, and execute permissions for the file.
  2689. The constants "oth_r", "oth_w", and "oth_x" can be AND'd with "mode"
  2690. to determine the read, write, and execute permissions for persons other
  2691. than the files owner who are not part of the file owner group.
  2692. The "dir_bit" constant can be AND'd with "mode" to determine if the file
  2693. really is a directory.
  2694.  
  2695. ------------------
  2696. 7.2.19 getfiletime
  2697. ------------------
  2698. Purpose: Returns the time a file was last modified.
  2699. Syntax:
  2700.    getfiletime-call = 'getfiletime' '(' name ',' hour ',' min ',' sec ')'
  2701.  
  2702.    name = character-expression | string-expression
  2703.  
  2704.    hour = integer-variable
  2705.  
  2706.    min = integer-variable
  2707.  
  2708.    sec = integer-variable
  2709.  
  2710. Standard Pascal: No
  2711. Notes:
  2712. "name" is the name of the file to test.
  2713. "hour" stores the hour the file was last modified (0 to 23)
  2714. "min" stores the minute the file was last modified (0 to 59)
  2715. "sec" stores the second the file was last modified (0 to 61)
  2716.  
  2717. --------------
  2718. 7.2.20 gettime
  2719. --------------
  2720. Purpose: Retrieves the current system time.
  2721. Syntax:
  2722.    gettime-call = 'gettime' '(' hour ',' min ',' sec ')'
  2723.  
  2724.    hour = integer-variable
  2725.  
  2726.    min = integer-variable
  2727.  
  2728.    sec = integer-variable
  2729.  
  2730. Standard Pascal: No
  2731. Notes:
  2732. "hour" stores the current hour (0 to 23)
  2733. "min" stores the current minute (0 to 59)
  2734. "sec" stores the current second (0 to 61)
  2735.  
  2736. -----------
  2737. 7.2.21 halt
  2738. -----------
  2739. Purpose: Terminates the program and optionally returns an integer value
  2740.      to the program's caller.
  2741. Syntax:
  2742.    halt-call = 'halt' [ '(' i ')' ]
  2743.  
  2744.    i = integer-expression
  2745.  
  2746. Standard Pascal: No
  2747. Notes:
  2748. "i" if specified is the value returned by the program.
  2749.  
  2750. ----------
  2751. 7.2.22 inc
  2752. ----------
  2753. Purpose: Increments an ordinal variable by a specified amount or by one.
  2754. Syntax:
  2755.    inc-call = 'inc' '(' o [ ',' amount ] ')'
  2756.  
  2757.    o = ordinal-variable
  2758.  
  2759.    amount = integer-expression
  2760.  
  2761. Standard Pascal: No
  2762. Notes:
  2763. If "amount" is omitted then "o" is incremented by one.
  2764. Using this function is slightly more efficient than using
  2765.     o := o + amount;
  2766.  
  2767. -------------
  2768. 7.2.23 insert
  2769. -------------
  2770. Purpose: Inserts a component into a string or a list.
  2771. Syntax:
  2772.    insert-call = insert-list | insert-string
  2773.  
  2774.    insert-list = 'insert' '(' v ',' l [ ',' p ] ')'
  2775.  
  2776.    insert-string = 'insert' '(' s1 ',' s2 [ ',' p ] ')'
  2777.  
  2778.    v = expression
  2779.  
  2780.    l = list-variable
  2781.  
  2782.    s1 = character expression | string-expression
  2783.  
  2784.    s2 = string-variable
  2785.  
  2786. Standard Pascal: No
  2787. Notes:
  2788. "v" is the component to insert into the list "l", and must be assignment
  2789.    compatible with the list's component type.
  2790. "l" is the list variable to insert into.
  2791. "s1" s the component to insert into the string "s2".
  2792. "s2" is the string variable to insert into.
  2793. "p" if specified indicates the position to perform the insertion. If "p" is
  2794.    omitted the insertion is performed at the end of the string or list.
  2795.  
  2796. ------------
  2797. 7.2.24 mkdir
  2798. ------------
  2799. Purpose: Makes a directory
  2800. Syntax:
  2801.    mkdir-call = 'mkdir' '(' name ')'
  2802.  
  2803.    name = character-expression | string-expression
  2804. Standard Pascal: No
  2805. Notes:
  2806. "name" is the name of the directory to create.
  2807.  
  2808. ----------
  2809. 7.2.25 new
  2810. ----------
  2811. Purpose: Initializes a list or creates a variable for a pointer.
  2812. Syntax:
  2813.    new-call = new-list | new-pointer
  2814.  
  2815.    new-list = 'new' '(' l ')'
  2816.  
  2817.    new-pointer = 'new' '(' p ')'
  2818.  
  2819.    l = list-variable
  2820.  
  2821.    p = pointer-variable
  2822.  
  2823. Standard Pascal: Yes
  2824. Notes:
  2825.  
  2826. -----------
  2827. 7.2.26 open
  2828. -----------
  2829. Purpose: Open a file.
  2830. Syntax:
  2831.    open-call = 'open' '(' fv ',' name ',' mode ')'
  2832.  
  2833.    fv = file-variable
  2834.  
  2835.    name = character-expression | string-expression
  2836.  
  2837.    mode = integer-expression
  2838.  
  2839. Standard Pascal: No
  2840. Notes:
  2841. "name" is the name of the file to open.
  2842. "mode" is the file mode. You can use the built-in constants "readmode",
  2843. "writemode", and "appendmode" to specify the file mode. The "readmode"
  2844. and "writemode" constants can be added or or'd together to specify that
  2845. the file be opened for both reading and writing.
  2846.  
  2847. For example
  2848.  
  2849.    open(f, "test.txt", readmode+writemode);
  2850.  
  2851. will open the file "test.txt" for both reading and writing. It is an
  2852. error if the file "test.txt" does not exist. If you wish to create a new
  2853. file for reading and writing you must create it first with "rewrite" or
  2854. using "open" with "writemode" only, and then close the filee, before
  2855. opening it again for reading and writing.
  2856.  
  2857. See also "7.2.1 append", "7.2.38 reset", "7.2.40 rewrite".
  2858.  
  2859. --------------
  2860. 7.2.27 opendir
  2861. --------------
  2862. Purpose: Opens a directory.
  2863. Syntax:
  2864.    opendir-call = 'opendir' '(' d ')'
  2865.  
  2866.    d = directory-variable
  2867.  
  2868. Standard Pascal: No
  2869. Notes:
  2870. Irie Pascal allows you to open, read, rewind, and close directories
  2871. (See "7.2.6 closedir", "7.2.35 readdir", and "7.2.39 rewinddir").
  2872.  
  2873. -----------
  2874. 7.2.28 pack
  2875. -----------
  2876. Purpose: Copies some or all of the contents of an unpacked array
  2877.      into a packed array.
  2878. Syntax:
  2879.    pack-call = 'pack' '(' u ',' x ',' p ')'
  2880.  
  2881.    u = unpacked-array-variable
  2882.  
  2883.    x = expression
  2884.  
  2885.    p = packed-array-variable
  2886.  
  2887.     where "u" is an unpacked array
  2888.       and "x" is an expression that is assignment compatible
  2889.           with the index type of "u" and specifies the first
  2890.           element of "u" to copy.
  2891.       and "p" is a packed array
  2892. Standard Pascal: Yes
  2893. Notes:
  2894. The elements of "u" and "a" must have the same type.
  2895.  
  2896. For example suppose you have the following arrays
  2897.  
  2898.    p : packed array[1..10] of integer;
  2899.    u : array[-10..10] of integer;
  2900.  
  2901. then
  2902.  
  2903.    pack(u, 1, p)
  2904.  
  2905. copies elements 1 to 10 of "u" into elements 1 to 10 of "p".
  2906. Or in a more complicated example
  2907.  
  2908.    pack(u, 9, p)
  2909.  
  2910. copies elements 9 to 10 of "u" into elements 1 to 2 of "p"
  2911.  
  2912. -----------
  2913. 7.2.29 page
  2914. -----------
  2915. Purpose: This procedure is supposed to affect a text file in such
  2916.      a way that subsequent output to the file appears on a new
  2917.      page.
  2918. Syntax:
  2919.    page-call = 'page' '(' t ')'
  2920.  
  2921.    t = text-file-variable
  2922.  
  2923. Standard Pascal: Yes
  2924. Notes:
  2925. Currently this procedure simply writes a form-feed to the text file.
  2926.  
  2927. ----------
  2928. 7.2.30 put
  2929. ----------
  2930. Purpose: Writes the contents of a file's buffer to a file and
  2931.      empties the file's buffer leaving it undefined.
  2932. Syntax:
  2933.    put-call = 'put' '(' f ')'
  2934.  
  2935.    f = file-variable
  2936.  
  2937. Standard Pascal: Yes
  2938. Notes:
  2939. If "f" is a file variable then the file's buffer can be accessed
  2940. with "f^" or "f@".
  2941.  
  2942. ----------------
  2943. 7.2.31 randomize
  2944. ----------------
  2945. Purpose: Initializes the random number generator with a seed.
  2946. Syntax:
  2947.    randomize-call = 'randomize' [ '(' i ')' ]
  2948.  
  2949.    i = integer-expression
  2950.  
  2951. Standard Pascal: No
  2952. Notes:
  2953. "i" if specified is the seed used to initialize the random number generator.
  2954. If "i" is omitted then the random number generated is initialized with a
  2955. seed derived from the current system date and time. Specifying "i" is useful
  2956. if you want a repeatable sequence of random numbers.
  2957.  
  2958. --------------
  2959. 7.2.32 rawread
  2960. --------------
  2961. Purpose: Reads up to a specified number of characters into a
  2962.      character buffer.
  2963. Syntax:
  2964.    rawread-call = 'rawread' '(' f ',' buffer ',' count ',' actual ')'
  2965.  
  2966.    f = file-variable
  2967.  
  2968.    buffer = array-variable
  2969.  
  2970.    count = integer-expression
  2971.  
  2972.    actual = integer-variable
  2973.  
  2974. Standard Pascal: No
  2975. Notes:
  2976. "buffer" must be a packed array of char variable and stores the characters
  2977.    read by this procedure.
  2978. "count" specifies the maximum number of characters to read.
  2979. "actual" stores the actual number of characters read by this procedure.
  2980. "actual" may be less than "count" if there was an I/O error (you can check
  2981. for this by disabling I/O checking and using the IOResult function) or if
  2982. end of file was reached.
  2983.  
  2984. ---------------
  2985. 7.2.33 rawwrite
  2986. ---------------
  2987. Purpose: Writes up to a specified number of characters from a character
  2988.      buffer to a file.
  2989. Syntax:
  2990.    rawwrite-call = 'rawwrite' '(' f ',' buffer ',' count ',' actual ')'
  2991.  
  2992.    f = file-variable
  2993.  
  2994.    buffer = array-variable
  2995.  
  2996.    count = integer-expression
  2997.  
  2998.    actual = integer-variable
  2999.  
  3000. Standard Pascal: No
  3001. Notes:
  3002. "buffer" must be a packed array of char variable and stores the characters
  3003.    to be written by this procedure.
  3004. "count" specifies the maximum number of characters to write.
  3005. "actual" stores the actual number of characters written by this procedure.
  3006. "actual" may be less than "count" if there was an I/O error (you can check
  3007. for this by disabling I/O checking and using the IOResult function).
  3008.  
  3009. -----------
  3010. 7.2.34 read
  3011. -----------
  3012. Purpose: This procedure reads data from a file into one or more variables.
  3013. Syntax:
  3014.    read-call = 'read' read-parameter-list
  3015.  
  3016.    read-parameter-list =
  3017.      '(' [ file-variable ',' ] variable-access { ',' variable-access } ')'
  3018.  
  3019. Standard Pascal: Yes
  3020. Notes:
  3021. If the file-variable is omitted then the built-in text file variable
  3022. "input" is used.
  3023. When this procedure reads from a text file it first attempts to convert
  3024. the text data into binary data suitable for storage in variables. In
  3025. addition when reading from a text file the variables in the variable list
  3026. must be of type real, string, integer, char, or subrange of integer.
  3027.  
  3028. --------------
  3029. 7.2.35 readdir
  3030. --------------
  3031. Purpose: Reads a directory (i.e. retrieves the name of a file in the
  3032.      directory).
  3033. Syntax:
  3034.    readdir-call = 'readdir' '(' d ',' name ')'
  3035.  
  3036.    d = directory-variable
  3037.  
  3038.    name = string-variable
  3039.  
  3040.     where "d" is a directory variable (i.e. a variable of the built-in
  3041.       type "dir").
  3042. Standard Pascal: No
  3043. Notes:
  3044. "d" is the directory variable associated with the directory to read.
  3045. "name" stores the filename of the next file in the directory.
  3046. See also "7.2.6 closedir", "7.2.27 opendir", and "7.2.39 rewinddir".
  3047.  
  3048. -------------
  3049. 7.2.36 readln
  3050. -------------
  3051. Purpose: This procedure reads a line of data from a text file into one or
  3052.      more variables. Any data left on the line after the read is ignored.
  3053. Syntax:
  3054.    readln-call = 'readln' readln-parameter-list
  3055.  
  3056.    readln-parameter-list =
  3057.      [ '(' ( file-variable | variable-access ) { ',' variable-access } ')' ]
  3058.  
  3059. Standard Pascal: Yes
  3060. Notes:
  3061. If the file-variable is omitted then the built-in text file variable
  3062. "input" is used.
  3063. When this procedure reads from a text file it first attempts to convert
  3064. the text data into binary data suitable for storage in variables. In
  3065. addition when reading from a text file the variables in the variable list
  3066. must be of type real, string, integer, char, or subrange of integer.
  3067.  
  3068. -------------
  3069. 7.2.37 rename
  3070. -------------
  3071. Purpose: Renames the file a file.
  3072. Syntax:
  3073.    rename-call = 'rename' '(' f ',' name ')'
  3074.  
  3075.    f = file-variable
  3076.  
  3077.    name = character-expression | string-expression
  3078.  
  3079. Notes:
  3080. This procedure changes the name of the file associated with the
  3081. file variable "f" to "name". This is more than just changing the name
  3082. associated with the file variable, the actual name of the file is changed.
  3083.  
  3084. ------------
  3085. 7.2.38 reset
  3086. ------------
  3087. Purpose: Opens a file for reading.
  3088. Syntax:
  3089.    reset-call = 'reset' '(' f [ ',' name ] ')'
  3090.  
  3091.    f = file-variable
  3092.  
  3093.    name = character-expression | string-expression
  3094.  
  3095. Standard Pascal: Yes
  3096. Notes:
  3097. If "name" is specified then "name" is assigned to the file variable before
  3098. the file is opened (the file must be closed). See also "7.2.1 append",
  3099. "7.2.40 rewrite", "7.2.3 assign", and "7.2.42 seek".
  3100.  
  3101. ----------------
  3102. 7.2.39 rewinddir
  3103. ----------------
  3104. Purpose: Rewinds a directory so that reads start with the first
  3105.      file in the directory.
  3106. Syntax:
  3107.    rewind-call = 'rewinddir' '(' d ')'
  3108.  
  3109.    d = directory-variable
  3110.  
  3111. Standard Pascal: No
  3112. Notes:
  3113. See also "7.2.6 closedir", "7.2.27 opendir", and "7.2.35 readdir".
  3114.  
  3115. --------------
  3116. 7.2.40 rewrite
  3117. --------------
  3118. Purpose: Opens a file for writing.
  3119. Syntax:
  3120.    rewrite-call = 'rewrite' '(' f [ ',' name ] ')'
  3121.  
  3122.    f = file-variable
  3123.  
  3124.    name = character-expression | string-expression
  3125.  
  3126. Standard Pascal: Yes
  3127. Notes:
  3128. If the file exists it's contents are deleted.
  3129. If the file does not exist it is created.
  3130. If a filename ("n") is specified then the filename is assigned to the
  3131. file variable before the file is opened (the file must be closed). See
  3132. also "7.2.1 append", "7.2.3 assign", "7.2.38 reset", and "7.2.42 seek".
  3133.  
  3134. ------------
  3135. 7.2.41 rmdir
  3136. ------------
  3137. Purpose: Removes (deletes) a directory
  3138. Syntax:
  3139.    rmdir-call = 'rmdir' '(' name ')'
  3140.  
  3141.    name = character-expression | string-expression
  3142.  
  3143. Standard Pascal: No
  3144. Notes:
  3145. "name" is the name of the directory to delete.
  3146.  
  3147. -----------
  3148. 7.2.42 seek
  3149. -----------
  3150. Purpose: Sets the position indicator for a file.
  3151. Syntax:
  3152.    seek-call = 'seek' '(' f ',' offset ')'
  3153.  
  3154.    f = file-variable
  3155.  
  3156.    offset = integer-expression
  3157.  
  3158. Standard Pascal: No
  3159. Notes:
  3160. "offset" specifies the new position indicator for the file.
  3161. The file associated with "f" must be open.
  3162.  
  3163. ------------------
  3164. 7.2.43 setfiledate
  3165. ------------------
  3166. Purpose: Sets a files date (i.e. last modification date).
  3167. Syntax:
  3168.    setfiledate-call = 'setfiledate' '(' f ',' year ',' mon ',' day ')'
  3169.  
  3170.    f = file-variable
  3171.  
  3172.    year = integer-expression
  3173.  
  3174.    mon = integer-expression
  3175.  
  3176.    day = integer-expression
  3177.  
  3178. Standard Pascal: No
  3179. Notes:
  3180. "year" specifies the year.
  3181. "mon" specifies the month (1 to 12)
  3182. "day" specifies the day (1 to 31).
  3183.  
  3184. ------------------
  3185. 7.2.44 setfiletime
  3186. ------------------
  3187. Purpose: Sets a files time (i.e. last modification time).
  3188. Syntax:
  3189.    setfiletime-call = 'setfiletime' '(' f ',' hour ',' min ',' sec ')'
  3190.  
  3191.    f = file-variable
  3192.  
  3193.    hour = integer-expression
  3194.  
  3195.    min = integer-expression
  3196.  
  3197.    sec = integer-expression
  3198.  
  3199. Standard Pascal: No
  3200. Notes:
  3201. "hour" specifies the hour (0 to 23)
  3202. "min" specifies the minute (0 to 59)
  3203. "sec" specifies the second (0 to 61).
  3204.  
  3205. ------------
  3206. 7.2.45 sleep
  3207. ------------
  3208. Purpose: Pauses execution of the program for a specified number of seconds.
  3209. Syntax:
  3210.    sleep-call = 'sleep' '(' i ')'
  3211.  
  3212.    i = integer-expression
  3213.  
  3214. Standard Pascal: No
  3215. Notes:
  3216. "i" specifies the number of seconds to sleep.
  3217.  
  3218. ----------
  3219. 7.2.46 str
  3220. ----------
  3221. Purpose: Converts an integer or real expression into a string and
  3222.      assigns the converted string to a variable.
  3223. Syntax:
  3224.    str-call = str-integer | str-real
  3225.  
  3226.    str-integer = 'str' '(' i [':' width] ',' s ')'
  3227.  
  3228.    str-real = 'str' '(' r [ ':' width [ ':' frac ] ] ',' s ')'
  3229.  
  3230.    i = integer-expression
  3231.  
  3232.    width = integer-expression
  3233.  
  3234.    s = string-variable
  3235.  
  3236.    r = real-expression
  3237.  
  3238.    frac = integer-expression
  3239.  
  3240. Standard Pascal: No
  3241. Notes:
  3242. "i" specifies the integer to convert
  3243. "s" stores the converted string.
  3244. "width" specifies the maximum width of the converted string
  3245. "frac" specifies the number of digits after the decimal point.
  3246.  
  3247. If "width" is omitted then eight is assumed for integer conversion
  3248. and nine is assumed for real conversions.
  3249.  
  3250. If "frac" is omitted then the real expression is converted into a
  3251. string in exponential form.
  3252. If "frac" is present then the real expression is converted into
  3253. a string in fixed form.
  3254.  
  3255. For example
  3256.     str(1034:6, s) will store '  1034' in "s"
  3257.     str(3.1:8, s) will store '3.1E+001' in "s"
  3258.     str(-3.14:6:2, s) will store ' -3.14' in "s"
  3259. The string value is padded on the left if necessary.
  3260.  
  3261. -------------
  3262. 7.2.47 unpack
  3263. -------------
  3264. Purpose: Copies some or all of the elements of a packed array into
  3265.      an unpacked array.
  3266. Syntax:
  3267.    unpack-call = 'unpack' '(' p ',' u ',' x ')'
  3268.  
  3269.    p = packed-array-variable
  3270.  
  3271.    x = expression
  3272.  
  3273.    u = unpacked-array-variable
  3274.  
  3275. Standard Pascal: Yes
  3276. Notes:
  3277. "x" must be assignment compatible with the index type of "u" and specifies
  3278. the position in "u" to receive the first array element.
  3279. The elements of "u" and "a" must have the same type.
  3280.  
  3281. For example suppose you have the following arrays
  3282.  
  3283.    p : packed array[1..10] of integer;
  3284.    u : array[-10..10] of integer;
  3285.  
  3286. then
  3287.  
  3288.    unpack(p, u, 1)
  3289.  
  3290. copies elements -10 to -1 of "p" into elements 1 to 10 of "u".
  3291.  
  3292. ----------
  3293. 7.2.48 val
  3294. ----------
  3295. Purpose: Converts a string expression into an integer or real value
  3296.      and assigns the converted value to a variable.
  3297. Syntax:
  3298.    val-call = val-integer | val-real
  3299.  
  3300.    val-integer = 'val' '(' s ',' i ',' offset ')'
  3301.  
  3302.    val-real = 'val' '(' s ',' r ',' offset ')'
  3303.  
  3304.    s = character-expression | string-expression
  3305.  
  3306.    i = integer-variable
  3307.  
  3308.    r = integer-variable
  3309.  
  3310. Standard Pascal: No
  3311. Notes:
  3312. "i" stores the converted integer value
  3313. "r" stores the converted real value
  3314. "offset" stores the position of the first character in "s" that could not
  3315.   be converted or zero if all characters where converted.
  3316.  
  3317. For example given integer variables "i" and "x" the following statement
  3318.     val('123EB', i, x)
  3319. will store 123 in "i" and 4 in "x".
  3320.  
  3321. ------------
  3322. 7.2.49 write
  3323. ------------
  3324. Purpose: This procedure writes data from one or more variables into a file
  3325. Syntax:
  3326.    write-call = 'write' write-parameter-list
  3327.  
  3328.    write-parameter-list =
  3329.      '(' [ file-variable ',' ] write-parameter { ',' write-parameter } ')'
  3330.  
  3331.    write-parameter = expression [ ':' expression [ ':' expression ] ]
  3332.  
  3333. Standard Pascal: Yes
  3334. Notes:
  3335. When this procedure writes to a non-text file then the write-parameters
  3336. are simply expressions, and the binary value of the expressions are
  3337. written to the file.
  3338. When this procedure writes to a text file it first attempts to convert
  3339. the binary data stored in the variables into text data. In addition
  3340. when writing to a text file the variables in the variable list must
  3341. must be of type boolean, real, string, integer, subrange of integer,
  3342. or char.
  3343.  
  3344. --------------
  3345. 7.2.50 writeln
  3346. --------------
  3347. Purpose: This procedure writes a line of data from one or more variables
  3348.      into a text file
  3349. Syntax:
  3350.    writeln-call = 'writeln' writeln-parameter-list
  3351.  
  3352.    writeln-parameter-list =
  3353.      [ '(' ( file-variable | write-parameter ) { ',' write-parameter } ')' ]
  3354.  
  3355.    write-parameter = expression [ ':' expression [ ':' expression ] ]
  3356.  
  3357. Standard Pascal: Yes
  3358. Notes:
  3359. When this procedure writes to a text file it first attempts to convert
  3360. the binary data stored in the variables into text data. In addition
  3361. when writing to a text file the variables in the variable list must
  3362. must be of type boolean, real, string, integer, subrange of integer,
  3363. or char.
  3364.  
  3365. -------------
  3366. 8 Expressions
  3367. -------------
  3368. Expressions specify a sequence of operations to be performed that
  3369. result in a single value of a particular type.
  3370.  
  3371. The syntax for expressions is given below:
  3372.  
  3373.    expression = shift-expression [ relational-operator shift-expression]
  3374.  
  3375.    shift-expression = simple-expression [ shift-operator simple-expression]
  3376.  
  3377.    simple-expression = term { adding-operator term }
  3378.  
  3379.    term = factor { multiplying-operator factor }
  3380.  
  3381.    factor = [sign] unsigned-constant |
  3382.         [sign] variable-access |
  3383.         [sign] '(' expression ')' |
  3384.         function-designator |
  3385.         'not' factor |
  3386.         set-constructor
  3387.  
  3388.    sign = '+' | '-'
  3389.  
  3390.    unsigned-constant = unsigned-integer |
  3391.                unsigned-real |
  3392.                character-string |
  3393.                constant-identifier |
  3394.                'nil'
  3395.  
  3396.    variable-access = entire-variable |
  3397.              component-variable |
  3398.              identified-variable |
  3399.              buffer-variable
  3400.  
  3401.    entire-variable = variable-identifier
  3402.  
  3403.    component-variable = indexed-variable | field-designator
  3404.  
  3405.    indexed-variable =
  3406.       array-variable '[' index-expression { ',' index-expression } ']'
  3407.  
  3408.    field-designator = record-variable '.' field-specifier |
  3409.               field-designator-identifier
  3410.  
  3411.    field-specifier = field-identifier
  3412.  
  3413.    identified-variable = pointer-variable '^' | pointer-variable '@'
  3414.  
  3415.    buffer-variable = file-variable '^' | file-variable '@'
  3416.  
  3417.    set-constructor = '[' [ member-designator { ',' member-designator } ] ']'
  3418.  
  3419.    member-designator = expression [ '..' expression ]
  3420.  
  3421.    function-designator = function-identifier [ actual-parameter-list ]
  3422.  
  3423.    actual-parameter-list = '(' actual-parameter { ',' actual-parameter } ')'
  3424.  
  3425.    actual-parameter = expression |
  3426.               variable-access |
  3427.               procedure-identifier |
  3428.               function-identifier
  3429.               omitted-parameter
  3430.  
  3431.    omitted-parameter =
  3432.  
  3433.    relational-operator = '=' | '<>' | '<' | '<=' | '>' | '>=' | 'in'
  3434.  
  3435.    shift-operator = 'shl' | shr'
  3436.  
  3437.    adding-operator = '+' | '-' | 'or' | 'or_else' | 'xor'
  3438.  
  3439.    multiplying-operator = '*' | '/' | 'div' | 'mod' | 'and' | 'and_then'
  3440.  
  3441. -------------
  3442. 8.1 Operators
  3443. -------------
  3444. Below is a table of all the operators supported by Irie Pascal in
  3445. order of decreasing precedence. All operators on the same line have
  3446. the same precedence.
  3447.  
  3448.    -----------------------------
  3449.    not
  3450.    -----------------------------
  3451.    *  /  div  mod  and  and_then
  3452.    -----------------------------
  3453.    +  -  or  or_else  xor
  3454.    -----------------------------
  3455.    shl  shr
  3456.    -----------------------------
  3457.    =  <>  <  <=  >  >=  in
  3458.    -----------------------------
  3459.  
  3460. ------------------
  3461. 8.1.1 Not Operator
  3462. ------------------
  3463. The "not" operator takes a single operand and specifies one of two
  3464. operations depending on the type of the operand. If the operand is
  3465. of type boolean then the "not" operator specifies a boolean NOT (i.e
  3466. if the value of the operand is true the result of the operation is false
  3467. and if the value of the operand is false the result of the operation is
  3468. true). If the operand is of type integer then the "not" operator specifies
  3469. a bitwise NOT (i.e. the result of the operation is calculated by flipping
  3470. all the bits in the operand).
  3471.  
  3472. ----------------
  3473. 8.1.2 * Operator
  3474. ----------------
  3475. The "*" operator takes two operands and specifies one of two operations
  3476. depending on the type of the operands.
  3477.  
  3478. If the operands are of type integer or real then the "*" operator specifies
  3479. multiplication. If both operands are of type integer then the result of the
  3480. operation is of type integer. If both operands are of type real then the
  3481. result of the operation is of type real. If one operand is of type integer
  3482. and the other is of type real then the integer operand is converted to real
  3483. before the multiplication is performed and the result of the operation is of
  3484. type real.
  3485.  
  3486. If the operands are set-types then the "*" operator specifies set
  3487. intersection (i.e. the result of the operation is a set whose members
  3488. are those members common to both operands).
  3489.  
  3490. ----------------
  3491. 8.1.3 / Operator
  3492. ----------------
  3493. The "/" operator takes two operands and specifies division. The type of
  3494. the operands must be integer or real, and the integer operands are first
  3495. converted to real before the division is performed. The result of the
  3496. operation is of type real.
  3497.  
  3498. ------------------
  3499. 8.1.4 Div Operator
  3500. ------------------
  3501. The "div" operator takes two operands and specifies division. The type of
  3502. the operands must both be of type integer. The result of the operation is
  3503. of type integer (note: The remainder from the division is discarded).
  3504.  
  3505. ------------------
  3506. 8.1.5 Mod Operator
  3507. ------------------
  3508. The "mod" operator takes two operands and specifies modulus. The type of
  3509. the operands must both be of type integer. When the operands are positive
  3510. then the result of the operation is the remainder from dividing the left
  3511. operand by the right operand. The result of the operation is of type
  3512. integer. 
  3513.  
  3514. ------------------
  3515. 8.1.6 And Operator
  3516. ------------------
  3517. The "and" operator takes two operands and specifies one of two operations
  3518. depending on the type of the operands.
  3519.  
  3520. If the operands are of type boolean then the "and" operator specifies
  3521. boolean AND. The result of the operation is of type boolean and is equal
  3522. to true of both operands are true, and false if either operand is false.
  3523. By default short circuit evaluation is used when performing the boolean
  3524. AND (i.e. The left operand is evaluated first and if it is false then
  3525. the right operand is not evaluated because the result of the operation
  3526. must be false). The "-sc" compiler option that can be used to
  3527. enable/disable short-circuit evaluation.
  3528.  
  3529. If the operands are of type integer then the "and" operator specifies
  3530. bitwise AND. The result of the operation is of type integer.
  3531.  
  3532. -----------------------
  3533. 8.1.7 And_Then Operator
  3534. -----------------------
  3535. As an extension Irie Pascal supports the "and_then" operator, which takes
  3536. two boolean operands and specifies boolean AND. The result of the operation
  3537. is of type boolean. The difference between this operator and the "and"
  3538. operator is that this one can not be used to perform bitwise AND and
  3539. short circuit evaluation is always used when evaluating this operator.
  3540.  
  3541. ----------------
  3542. 8.1.8 + Operator
  3543. ----------------
  3544. The "+" operator takes one or two operands and specifies one of three
  3545. operations depending on the type of the operands.
  3546.  
  3547. If there is only one operand and it is of type integer or real then
  3548. this operator specifies unary-plus and in fact has no effect.
  3549.  
  3550. If there are two operands and they are of type integer or real then the "+"
  3551. operator specifies addition. If both operands are of type integer then the
  3552. result of the operation is of type integer. If both operands are of type
  3553. real then the result of the operation is of type real. If one operand is of
  3554. type integer and the other is of type real then the integer operand is
  3555. converted to real before the addition is performed and the result of the
  3556. operation is of type real.
  3557.  
  3558. If there are two operands and they are of set type then the "+" operator
  3559. specified set union (i.e. the result of the operation is a set with all
  3560. the members from either operand).
  3561.  
  3562. As an extension Irie Pascal supports the use of the "+" to specify string
  3563. concatenation where there are two operands and they are of type string or
  3564. char.
  3565.  
  3566. ----------------
  3567. 8.1.9 - Operator
  3568. ----------------
  3569. The "-" operator takes one or two operands and specifies one of two
  3570. operations depending on the type of the operands.
  3571.  
  3572. If there is only one operand and it is of type integer or real then
  3573. this operator specifies unary-minus and specifies unary-minus. The
  3574. result of this operation has the same type as it's operand and has the
  3575. same magnitude as it's operand but the opposite sign.
  3576.  
  3577. If there are two operands and they are of type integer or real then the "-"
  3578. operator specifies subtraction. If both operands are of type integer then
  3579. the result of the operation is of type integer. If both operands are of type
  3580. real then the result of the operation is of type real. If one operand is of
  3581. type integer and the other is of type real then the integer operand is
  3582. converted to real before the subtraction is performed and the result of the
  3583. operation is of type real.
  3584.  
  3585. If there are two operands and they are of set type then the "-" operator
  3586. specified set difference (i.e. the result of the operation is a set with
  3587. those members are in the left operand but not in the right operand).
  3588.  
  3589. ------------------
  3590. 8.1.10 Or Operator
  3591. ------------------
  3592. The "or" operator takes two operands and specifies one of two operations
  3593. depending on the type of the operands.
  3594.  
  3595. If the operands are of type boolean then the "or" operator specifies
  3596. boolean OR. The result of the operation is of type boolean and is equal
  3597. to true of either operand is true, and false if both operands are false.
  3598. By default short circuit evaluation is used when performing the boolean
  3599. OR (i.e. The left operand is evaluated first and if it is true then
  3600. the right operand is not evaluated because the result of the operation
  3601. must be true). The "-sc" compiler option that can be used to
  3602. enable/disable short-circuit evaluation.
  3603.  
  3604. If the operands are of type integer then the "or" operator specifies
  3605. bitwise OR. The result of the operation is of type integer.
  3606.  
  3607. -----------------------
  3608. 8.1.11 Or_Else Operator
  3609. -----------------------
  3610. As an extension Irie Pascal supports the "or_else" operator, which takes two
  3611. boolean operands and specifies boolean OR. The result of the operation is
  3612. of type boolean. The difference between this operator and the "or" operator
  3613. is that this one can not be used to perform bitwise OR and short circuit
  3614. evaluation is always used when evaluating this operator.
  3615.  
  3616. -------------------
  3617. 8.1.12 Xor Operator
  3618. -------------------
  3619. As an extension Irie Pascal supports the "xor" operator, which takes two
  3620. operands and specifies one of two operations depending on the type of the
  3621. operands.
  3622.  
  3623. If the operands are of type boolean then the "xor" operator specifies
  3624. boolean XOR. The result of the operation is of type boolean and is equal
  3625. to true if one but not both operands are true, and false if both operands
  3626. are false.
  3627.  
  3628. If the operands are of type integer then the "xor" operator specifies
  3629. bitwise XOR. The result of the operation is of type integer.
  3630.  
  3631. -------------------
  3632. 8.1.13 shl Operator
  3633. -------------------
  3634. As an extension Irie Pascal supports the "shl" operator, which takes two
  3635. operands of type integer and specifies bit-shift left. The result of the
  3636. operation is the left operand shifted left by the number of bits specified
  3637. by the right operand. The right operand must be greater than or equal to
  3638. zero.
  3639.  
  3640. -------------------
  3641. 8.1.14 shr Operator
  3642. -------------------
  3643. As an extension Irie Pascal supports the "shr" operator, which takes two
  3644. operands of type integer and specifies bit-shift right. The result of the
  3645. operation is the left operand shifted right by the number of bits specified
  3646. by the right operand. The right operand must be greater than or equal to
  3647. zero.
  3648.  
  3649. -----------------
  3650. 8.1.15 = Operator
  3651. -----------------
  3652. The "=" operator takes two operands and compares them for equality. If one
  3653. operand is of type integer and the other is of type real then the integer
  3654. operand is converted to real before the comparison is made. The result of
  3655. this operation is of type boolean and is true if the operands are equal
  3656. and false otherwise.
  3657.  
  3658. -----------------
  3659. 8.1.16 <> Operator
  3660. -----------------
  3661. The "<>" operator takes two operands and compares them for equality. If one
  3662. operand is of type integer and the other is of type real then the integer
  3663. operand is converted to real before the comparison is made. The result of
  3664. this operation is of type boolean and is true if the operands are not equal
  3665. and true otherwise.
  3666.  
  3667. -----------------
  3668. 8.1.17 < Operator
  3669. -----------------
  3670. The "<" operator takes two operands and compares them. If one operand is of
  3671. type integer and the other is of type real then the integer operand is
  3672. converted to real before the comparison is made. The result of this
  3673. operation is of type boolean and is true if the left operand is less than
  3674. the right operand.
  3675.  
  3676. ------------------
  3677. 8.1.18 <= Operator
  3678. ------------------
  3679. The "<=" operator takes two operands and specifies one of two operations
  3680. depending on the type of the operands.
  3681.  
  3682. The operands are simple types or string types then this operator compares
  3683. them. If one operand is of type integer and the other is of type real then
  3684. the integer operand is converted to real before the comparison is made.
  3685. The result of this operation is of type boolean and is true if the left
  3686. operand is less than or equal to the right operand.
  3687.  
  3688. If the operands are set types then the "<=" operator specifies set
  3689. inclusion. The result of this operation is true if all the members
  3690. of the left operand are in the right operand.
  3691.  
  3692. -----------------
  3693. 8.1.19 > Operator
  3694. -----------------
  3695. The ">" operator takes two operands and compares them. If one operand is of
  3696. type integer and the other is of type real then the integer operand is
  3697. converted to real before the comparison is made. The result of this
  3698. operation is of type boolean and is true if the left operand is greater
  3699. than the right operand.
  3700.  
  3701. ------------------
  3702. 8.1.20 >= Operator
  3703. ------------------
  3704. The ">=" operator takes two operands and specifies one of two operations
  3705. depending on the type of the operands.
  3706.  
  3707. The operands are simple types or string types then this operator compares
  3708. them. If one operand is of type integer and the other is of type real then
  3709. the integer operand is converted to real before the comparison is made.
  3710. The result of this operation is of type boolean and is true if the left
  3711. operand is greater than or equal to the right operand.
  3712.  
  3713. If the operands are set types then the ">=" operator specifies set
  3714. inclusion. The result of this operation is true if all the members
  3715. of the right operand are in the left operand, and is false otherwise.
  3716.  
  3717. ------------------
  3718. 8.1.21 In Operator
  3719. ------------------
  3720. The "in" operator takes two operands, the left operand is of set type
  3721. and the right operands of ordinal type. The result of this operation
  3722. is of type boolean and is true if the right operand is a member of the
  3723. left operand, and is false otherwise.
  3724.  
  3725. --------------------
  3726. 8.2 Compatible types
  3727. --------------------
  3728. Irie Pascal implements the type compatibility rules defined by Standard
  3729. Pascal (ISO/IEC 7185), and adds one more to support variable length
  3730. string types. The first four rules below are taken from ISO/IEC 7185 and
  3731. the last one is the one added to support variable length string types.
  3732.  
  3733. Types T1 and T2 shall be designated compatible if any of the following
  3734. statements is true:
  3735.  
  3736. 1. T1 and T2 are the same type.
  3737. 2. T1 is a subrange of T2, or T2 is a subrange of T1, or both T1 and T2 are
  3738.       subranges of the same host type.
  3739. 3. T1 and T2 are set-types of compatible base-types, and either both T1 and
  3740.    T2 are designated packed or neither T1 nor T2 is designated packed.
  3741. 4. T1 and T2 are fixed-length-string-types with the same number of
  3742.       components.
  3743. 5. Either T1 is a variable-length-string-type and T2 is a
  3744.       variable-length-string-type,
  3745.    or T1 is a variable-length-string-type and T2 is a
  3746.       fixed-length-string-type, and the number of components in T2 is less
  3747.       than or equal to the maximum length of T1,
  3748.    or T1 is a variable-length-string-type and T2 is the char-type
  3749.    or T2 is a variable-length-string-type and T1 is a
  3750.       fixed-length-string-type, and the number of components in T1 is less
  3751.       than or equal to the maximum length of T2,
  3752.    or T2 is a variable-length-string-type and T1 is the char-type.
  3753.  
  3754. ------------
  3755. 9 Statements
  3756. ------------
  3757. The statements in a program specify the specific actions that the program
  3758. can perform. Programs perform their actions (or run) by executing the
  3759. statements that they contain. Pascal programs begin executing at the first
  3760. statement in the main program block. Program execution generally flows
  3761. from left to right and top to bottom, however there are a number of
  3762. statements which can alter this flow of execution.
  3763.  
  3764. Statements can be grouped in a number of ways. For example statements
  3765. can be separated into two groups, simple statement and structured statements,
  3766. where simple statements are statements that do not contain other statements,
  3767. while structured statements are statements that do contain other statements.
  3768. Other groups of statements include conditional statements and repetitive
  3769. statements. Conditional statements allow programs to make decisions (i.e.
  3770. they test a particular condition and change the flow of execution depending
  3771. on the result). Repetitive statements allow the program to loop (i.e.
  3772. execute one or more statements repeatedly).
  3773.  
  3774. Labels can be placed in front of statements to mark them as targets for
  3775. "goto" statements. As an extension Irie Pascal allows labels to be
  3776. identifiers as well as sequences of digits. See also "3 Labels".
  3777.  
  3778. The syntax for statements is given below:
  3779.  
  3780.    statement = [ label ':' ] ( simple-statement | structured-statement )
  3781.  
  3782.    label = digit-sequence | identifier
  3783.  
  3784.    simple-statement = empty-statement |
  3785.               assignment-statement |
  3786.               procedure-statement |
  3787.               goto-statement
  3788.  
  3789.    structured-statement = compound-statement |
  3790.               conditional-statement |
  3791.               repetitive-statement |
  3792.               with-statement
  3793.  
  3794.    compound-statement = 'begin' statement-sequence 'end'
  3795.  
  3796.    statement-sequence = statement { ';' statement }
  3797.  
  3798.    conditional-statement = if-statement |
  3799.                case-statement
  3800.  
  3801.    repetitive-statement = repeat-statement |
  3802.               while-statement |
  3803.               for-statement
  3804.  
  3805. -------------------
  3806. 9.1 Empty Statement
  3807. -------------------
  3808. Empty statements don't do anything and are usually created when Pascal
  3809. syntax requires a statement to exist but you don't specify one.
  3810. For example if you write
  3811.  
  3812.    begin
  3813.    end
  3814.  
  3815. then technically according to Pascal syntax there must be a statement
  3816. between the "begin" and the "end", and since there is nothing there the
  3817. empty statement is said to exist there. Empty statements also commonly
  3818. occur when statements sequences have a trailing semi-colon. In Pascal the
  3819. semi-colon is used as a statement separator and not a statement terminator
  3820. so the following statement sequence
  3821.  
  3822.    a;
  3823.    b;
  3824.  
  3825. actually contains three statements, the statement "a", the statement "b"
  3826. and an empty statement following "b". Since a semi-colon follows "b" then
  3827. it must separate "b" from another statement.
  3828.  
  3829. The syntax for the empty statement is given below:
  3830.  
  3831.    empty-statement =
  3832.  
  3833.  
  3834. ------------------------
  3835. 9.2 Assignment Statement
  3836. ------------------------
  3837. Assignments statements specify that an expression is to be evaluated and
  3838. the result stored in a variable. The value produced from evaluating the
  3839. expression must be assignment compatible with the type of the variable
  3840. (See "9.2.1 Assignment Compatibility" for details).
  3841.  
  3842. For example
  3843.  
  3844.    x := 1+1
  3845.  
  3846. is a simple example. When this statement is executed the expression "1+1"
  3847. is evaluated, and the value "2" is placed in the variable "x".
  3848.  
  3849. The syntax for the assignment statement is given below:
  3850.  
  3851.    assignment-statement = variable-access ':=' expression
  3852.  
  3853.    variable-access = entire-variable |
  3854.              component-variable |
  3855.              identified-variable |
  3856.              buffer-variable
  3857.  
  3858.    entire-variable = variable-identifier
  3859.  
  3860.    component-variable = indexed-variable | field-designator
  3861.  
  3862.    indexed-variable =
  3863.       array-variable '[' index-expression { ',' index-expression } ']'
  3864.  
  3865.    field-designator = record-variable '.' field-specifier |
  3866.               field-designator-identifier
  3867.  
  3868.    field-specifier = field-identifier
  3869.  
  3870.    identified-variable = pointer-variable '^' | pointer-variable '@'
  3871.  
  3872.    buffer-variable = file-variable '^' | file-variable '@'
  3873.  
  3874. See "8 Expression" for the syntax of expressions.
  3875.  
  3876. ------------------------------
  3877. 9.2.1 Assignment Compatibility
  3878. ------------------------------
  3879. Irie Pascal implements the assignment compatibility rules defined by
  3880. Standard Pascal (ISO/IEC 7185), and adds one more to support variable
  3881. length string types. The first five rules below are taken from ISO/IEC 7185
  3882. and the last one is the one added to support variable length string types.
  3883.  
  3884. A value "V" of type T2 is assignment compatible with a type T1 if any of
  3885. the following is true:
  3886.  
  3887. 1. T1 and T2 are the same type, and that type is not a file type or a type
  3888.    which contains a file type.
  3889.  
  3890. 2. T1 is the real-type and T2 is the integer-type.
  3891.  
  3892. 3. T1 and T2 are compatible ordinal-types, and V is in the closed interval
  3893.    specified by T1.
  3894.  
  3895. 4. T1 and T2 are compatible set-types, and all the members of V are in the
  3896.    closed interval specified by the base-type of T1.
  3897.  
  3898. 5. T1 and T2 are fixed length string types with the same length.
  3899.  
  3900. 6. T1 is a variable length string type and either
  3901.       T2 is a variable length string type
  3902.       or T2 is a fixed length string type
  3903.       or T2 is a char-type.
  3904.    In addition the length of V must not be greater then the maximum
  3905.    length of T1.
  3906.  
  3907. ----------------------------------------------------
  3908. 9.2.1.1 Assignment compatibility with array indexing
  3909. ----------------------------------------------------
  3910. The value of an index-expression shall be assignment compatible with the
  3911. index-type of the array variable.
  3912.  
  3913. For example given:
  3914.  
  3915.    var x : array[1..10] of integer;
  3916.  
  3917. and
  3918.  
  3919.    x[i] := 20;
  3920.  
  3921. then "i" (the value of the index-expression) shall be assignment compatible
  3922. with "1..10" (the index-type of the array variable).
  3923.  
  3924. ------------------------------------------------------
  3925. 9.2.1.2 Assignment compatibility with value parameters
  3926. ------------------------------------------------------
  3927. When passing a parameter by value the actual-parameter shall be
  3928. assignment compatible with the type of the formal-parameter.
  3929.  
  3930. For example given:
  3931.  
  3932.    function IsDigit(c : char) : Boolean;
  3933.    begin
  3934.       if c in ['0'..'9'] then
  3935.      IsDigit := true
  3936.       else
  3937.      IsDigit := false
  3938.    end;
  3939.  
  3940. and
  3941.  
  3942.    while not IsDigit(key) do
  3943.        read(key)
  3944.  
  3945. then "key" (the actual-parameter in IsDigit(key) shall be
  3946. assignment compatible with "char" (the type of the formal-parameter).
  3947.  
  3948. --------------------------------------------
  3949. 9.2.1.3 Assignment compatibility with "read"
  3950. --------------------------------------------
  3951. When using the built-in procedure "read" to store an input value into
  3952. a variable the input value shall be assignment compatible with the type of
  3953. the variable to which it is stored.
  3954.  
  3955. For example given:
  3956.  
  3957.    var s : string[40];
  3958.  
  3959. and
  3960.  
  3961.    read(s);
  3962.  
  3963. then the value read in by "read(s)" must be assignment compatible with
  3964. "string[40]".
  3965.  
  3966. -----------------------------------------------------------
  3967. 9.2.1.4 Assignment compatibility with assignment statements
  3968. -----------------------------------------------------------
  3969. The value of the expression on the right-hand side of an assignment statement
  3970. shall be assignment compatible with the type of the left-hand side (i.e.
  3971. either the variable or the function-identifier on the left-hand side).
  3972.  
  3973. For example given:
  3974.  
  3975.    var age : 0..100;
  3976.  
  3977. and
  3978.  
  3979.    age := v;
  3980.  
  3981. then "v" (the right-hand side of the assignment statement) shall be
  3982. assignment compatible the "0..100" (the type of the left-hand side of the
  3983. assignment statement).
  3984.  
  3985. -------------------------------------------
  3986. 9.2.1.5 Assignment compatibility with "for"
  3987. -------------------------------------------
  3988. The initial value and the final value in a for-statement shall be
  3989. assignment compatible with the type of the control variable if the
  3990. statement of the for-statement is executed (See "9.10 For Statement").
  3991.  
  3992. For example given:
  3993.  
  3994.    for i := low to high do writeln(i);
  3995.  
  3996. then "low" (the initial value) and "high" (the final value) shall be
  3997. assignment compatible with the type of "i" (the control variable) if
  3998. "writeln(i)" is executed. NOTE: "writeln(i)" will get executed unless
  3999. "low" is greater than "high".
  4000.  
  4001. ---------------------------
  4002. 9.2.1.6 Transfer procedures
  4003. ---------------------------
  4004. In the statement pack(a,i,z) and unpack(z,a,i) the value of "i" shall be
  4005. assignment compatible with the index-type of "a".
  4006.  
  4007. For example given:
  4008.  
  4009.    var a : array[1..100] of real;
  4010.        z : packed array[1..100] of real;
  4011.        i : integer;
  4012.  
  4013. and
  4014.  
  4015.    pack(a,i,z) or unpack(z,a,i)
  4016.  
  4017. then "i" shall be assignment compatible with "1..100"
  4018. (the index-type of "a").
  4019.  
  4020. -----------------------
  4021. 9.3 Procedure Statement
  4022. -----------------------
  4023. Procedure statements specify that a procedure is to be executed and
  4024. that a list of arguments if any are to be passed into the procedure.
  4025. When procedures are executed program execution is transferred to the
  4026. first statement in the procedure's statement block. After the execution
  4027. of a procedure program execution resumes with the statement after the
  4028. procedure call (See "7 Functions And Procedures").
  4029.  
  4030. For example
  4031.  
  4032.    writeln('1 + 1 = ', 1+1)
  4033.  
  4034. is a simple example. When this statement is executed the parameters "'1+1'"
  4035. and "1+1" are passed into the procedure and then it is executed. In this case
  4036. the "writeln" procedure prints the parameters to the standard output stream.
  4037.  
  4038. The syntax for procedure statements is given below:
  4039.  
  4040.    procedure-statement = procedure-identifier
  4041.    (
  4042.        [ actual-parameter-list ] |
  4043.        read-parameter-list |
  4044.        readln-parameter-list |
  4045.        write-parameter-list |
  4046.        writeln-parameter-list
  4047.    )
  4048.  
  4049.    procedure-identifier = identifier
  4050.  
  4051.    actual-parameter-list = '(' actual-parameter { ',' actual-parameter } ')'
  4052.  
  4053.    actual-parameter = expression |
  4054.               variable-access |
  4055.               procedure-identifier |
  4056.               function-identifier |
  4057.               omitted-parameter
  4058.  
  4059.    omitted-parameter =
  4060.  
  4061.    read-parameter-list =
  4062.      '(' [ file-variable ',' ] variable-access { ',' variable-access } ')'
  4063.  
  4064.    readln-parameter-list =
  4065.      [ '(' ( file-variable | variable-access ) { ',' variable-access } ')' ]
  4066.  
  4067.    write-parameter-list =
  4068.      '(' [ file-variable ',' ] write-parameter { ',' write-parameter } ')'
  4069.  
  4070.    write-parameter = expression [ ':' expression [ ':' expression ] ]
  4071.  
  4072.    writeln-parameter-list =
  4073.      [ '(' ( file-variable | write-parameter ) { ',' write-parameter } ')' ]
  4074.  
  4075. ------------------
  4076. 9.4 Goto Statement
  4077. ------------------
  4078. Goto statements specify that program execution is to be transferred to
  4079. the statement prefixed by the goto statement's label. Standard
  4080. (ISO/IEC 7185) Pascal describes the rules governing the use of
  4081. goto statements as follows:
  4082.  
  4083. A label, if any, of a statement S shall be designated as prefixing S.
  4084. The label shall be permitted to occur in a goto-statement G if and only
  4085. if any of the following three conditions is satisfied.
  4086.  
  4087.    a) S contains G.
  4088.    b) S is a statement of a statement-sequence containing G.
  4089.    c) S is a statement of the statement-sequence of the compound-statement
  4090.       of the statement-part of a block containing G.
  4091.  
  4092. To fully understand these rules you will probably need a copy of the
  4093. Standard (ISO/IEC 7185) but the fully explanation should suffice for
  4094. most people.
  4095.  
  4096. The rules are basically saying that you can't use a goto statement to
  4097. transfer execution into the middle of a statement. The first two rules
  4098. cover goto statements that refer to statements in the current block,
  4099. while the last rule covers goto statements that refer to statements in
  4100. an enclosing block.
  4101.  
  4102. If a goto statement transfers execution out of the current block then
  4103. the call-stack is unwound until the block containing the statement
  4104. referred to be the goto statement is reached.
  4105. So for example if the main program calls a procedure A, and procedure A
  4106. calls procedure B, and procedure B calls procedure C, and a goto statement
  4107. in procedure C transfers execution back to procedure A then procedures
  4108. C and B are terminated.
  4109.  
  4110. Below is a simple program illustrating the use of the goto statement
  4111.  
  4112.    program ten(output);
  4113.    label loop;
  4114.    var
  4115.       count : integer;
  4116.    begin
  4117.       count := 1;
  4118.       loop: writeln(count);
  4119.       count := count + 1;
  4120.       if count <= 10 then goto loop
  4121.    end.
  4122.  
  4123. NOTE: The label "loop" used in this program is declared before it is used
  4124. (which is a requirement for all labels).
  4125.  
  4126. The syntax for goto statements is given below:
  4127.  
  4128.    goto-statement = 'goto' label
  4129.  
  4130.    label = digit-sequence | identifier
  4131.  
  4132. ----------------------
  4133. 9.5 Compound Statement
  4134. ----------------------
  4135. Compound statements are used to group a number of statements into a
  4136. single statement. When a compound statement is executed, program execution
  4137. is transferred to the first statement in the statement group and generally
  4138. continues left to right, top to bottom unless diverted by one of the
  4139. statements executed. You usually use compound statements when Pascal
  4140. syntax says that only one statement is allowed at a particular point but you
  4141. want to put more than one, so you put the statements in a compound statement
  4142. and Pascal syntax is happy because the compound statement is a single
  4143. statement.
  4144.  
  4145. For example look at the program fragment below:
  4146.  
  4147.    write('Do you want to continue');
  4148.    readln(answer);
  4149.    if (answer = 'n') or (answer = 'N') then
  4150.      begin
  4151.     writeln('Program terminated by user');
  4152.     halt
  4153.      end
  4154.  
  4155. here we want to write a message to the screen and stop if the user
  4156. answers "n" or "N", but this requires two statements and the then part
  4157. of an if statement allows only a single statement. The solution as you
  4158. can see is just to put the two statements into a compound statement.
  4159.  
  4160. The syntax for compound statements is given below:
  4161.  
  4162.    compound-statement = 'begin' statement-sequence 'end'
  4163.  
  4164.    statement-sequence = statement { ';' statement }
  4165.  
  4166. ----------------
  4167. 9.6 If Statement
  4168. ----------------
  4169. If statements conditionally execute one or two statements. If statements
  4170. contain a boolean expression, a "then-part", and may optionally contain an
  4171. "else-part". When an if statement is executed the boolean expression is
  4172. evaluated and what happens next depends on the result of the evaluation.
  4173. If the expression is evaluated and found to be true then the statement in
  4174. the "then-part" is executed, and program execution resumes at the statement
  4175. after the if statement.
  4176. If the expression is evaluated and found to be false then if an "else-part"
  4177. is present the statement in the "else-part" is executed and program control
  4178. resumes at the statement after the if statement, if an else part is not
  4179. present then program execution is transferred immediately to the statement
  4180. after the if statement.
  4181.  
  4182. For example
  4183.  
  4184.    if x > y then
  4185.       writeln('x is greater than y')
  4186.    else
  4187.       writeln('x is NOT greater than y')
  4188.  
  4189. is an if statement.
  4190. When this statement is executed the boolean expression "x > y" is evaluated
  4191. and if true the statement "writeln('x is greater than y')" is executed,
  4192. and if the boolean expression is false the statement
  4193. "writeln('x is NOT greater than y')" is executed.
  4194.  
  4195. The syntax for if statements is given below:
  4196.  
  4197.    if-statement = 'if' boolean-expression then-part [ else-part ]
  4198.  
  4199.    then-part = 'then' statement
  4200.  
  4201.    else-part = 'else' statement
  4202.  
  4203. ------------------
  4204. 9.7 Case Statement
  4205. ------------------
  4206. Case statements conditionally execute one, two, or more statements.
  4207. Case statements contain an ordinal expression, zero, one or more case list
  4208. elements, and optionally a case statement completer. Case list elements
  4209. contain one or more constants and a statement. Case statement completers
  4210. contain a statement sequence. When a case statement is executed the ordinal
  4211. expression is evaluated and the value used to conditionally execute either
  4212. the statement in one of the case list elements or the statement sequence in
  4213. the case statement completer. If the expression evaluates to a value equal
  4214. to one of the constants in a case list element then the statement in that
  4215. case list element is executed. If the expression evaluates to a value that
  4216. is not equal to one of the constants in a case list element then the
  4217. statement sequence in the case statement completer is executed (if there is
  4218. no case statement completer then this is an error). After executing either
  4219. the statement in the case list element or the statement sequence in the
  4220. case statement completer program execution resumes at the statement after
  4221. the case statement.
  4222.  
  4223. Constant ranges can be used to specify a number of contiguous constants
  4224. (for example 1..5 is the same as 1, 2, 3, 4, 5).
  4225.  
  4226. No two case list elements can contain the same constant, so
  4227.  
  4228.    case x of
  4229.     1, 2, 3 : write('1 to 3');
  4230.     2 :  write('2');
  4231.    end
  4232.  
  4233. is an error since both case list elements contain "2".
  4234.  
  4235. For example the program fragment below shows an ordinal type and
  4236. a procedure with a case statement.
  4237.  
  4238.    type
  4239.        DayOfWeek =
  4240.     (monday, tuesday, wednesday, thursday, friday, saturday, sunday);
  4241.  
  4242.    procedure WriteDayOfWeek(day : DayOfWeek);
  4243.    begin
  4244.       case day of
  4245.      monday:    write('monday');
  4246.      tuesday:   write('tuesday');
  4247.      wednesday: write('wednesday');
  4248.      thursday:  write('thursday');
  4249.      friday:    write('friday');
  4250.      saturday:  write('saturday');
  4251.      sunday:    write('sunday');
  4252.       end
  4253.    end;
  4254.  
  4255. When the case statement is executed the ordinal expression "day" is evaluated
  4256. and if it is equal to "tuesday" for example then since the second case list
  4257. element contains a constant equal to "tuesday" then the statement in the
  4258. second case list element is executed (i.e. write('tuesday')).
  4259.  
  4260. Below is a slightly more complex example.
  4261.  
  4262.    program example(input, output);
  4263.    var
  4264.       c : char;
  4265.    begin
  4266.       write('Enter a digit :');
  4267.       readln(c);
  4268.       case c of
  4269.       '0'..'9' : writeln('OK');
  4270.       'a'..'z', 'A'..'Z' : writeln('That is a letter');
  4271.       otherwise writeln('What is that?');
  4272.       end
  4273.    end.
  4274.  
  4275. When the case statement is executed the ordinal expression "c" is
  4276. evaluated and the value used as follows:
  4277. If the value is a digit then the statement in the first case list element is
  4278. executed.
  4279. If the value is a letter then the statement in the second case list elements
  4280. is executed.
  4281. If the value is not a digit or a letter then the statement sequence in the
  4282. case statement completer is executed.
  4283.  
  4284. Due to an implementation limit Irie Pascal handles case statements
  4285. differently depending on the type of the ordinal expression.
  4286. If the ordinal expression in the case statement has a type with less than or
  4287. equal to 1024 values then Irie Pascal implements the case statement using a
  4288. jump table and the rule that no two case list elements can have the same
  4289. constant is enforced. In addition with the table implementation the ordinal
  4290. expression is evaluated only once.
  4291. If the ordinal expression in the case statement has a type with more than
  4292. 1024 values then Irie Pascal implements the case statement as a series of
  4293. if statements and the rule that no two case list elements can have the same
  4294. constant is NOT enforced. In addition with the if statement implementation
  4295. the ordinal expression is evaluated once for each case list element until
  4296. a match is found.
  4297. In practice the only integer expression are likely to have types with ranges
  4298. greater than 1024. You could create an enumerated type with more than
  4299. 1024 values but that is unlikely.
  4300.  
  4301. The syntax for case statements is given below:
  4302.  
  4303.    case-statement = 'case' case-index case-body [ ';' ] 'end'
  4304.  
  4305.    case-index = ordinal-expression
  4306.  
  4307.    case-body = case-list-elements [ [ ';' ] case-statement-completer ] |
  4308.            case-statement-completer
  4309.  
  4310.    case-list-elements = case-list-element { ';' case-list-element }
  4311.  
  4312.    case-list-element = case-constant-list ':' statement
  4313.  
  4314.    case-constant-list = case-specifier { ',' case-specifier }
  4315.  
  4316.    case-specifier = case-constant [ '..' case-constant ]
  4317.  
  4318.    case-constant = ordinal-constant
  4319.  
  4320.    case-statement-completer = 'otherwise' statement-sequence
  4321.  
  4322. --------------------
  4323. 9.8 Repeat Statement
  4324. --------------------
  4325. Repeat statements are used to repeatedly execute one or more statements
  4326. in a loop. Repeat statements contain a statement sequence and a loop
  4327. condition. When a repeat statement is executed the statement sequence is
  4328. executed as long as the loop condition is satisfied. The loop condition
  4329. is tested after the statement sequence is executed so the statement sequence
  4330. will always be executed at least once. The loop condition is a boolean
  4331. expression and is satisfied as long as the expression evaluates to false.
  4332. Usually the statement sequence will perform some action that will eventually
  4333. cause the loop condition to fail and thus terminate the loop. It is also
  4334. possible to use a goto statement to terminate the loop.
  4335.  
  4336. For example below is a very simple program which illustrates the use
  4337. of the repeat statement.
  4338.  
  4339.    program ten(output);
  4340.    var
  4341.       count : 1..11;
  4342.    begin
  4343.       count := 1;
  4344.       repeat
  4345.     writeln(count);
  4346.     count := count + 1
  4347.       until count > 10
  4348.    end.
  4349.  
  4350. The syntax for repeat statements is given below
  4351.  
  4352.   repeat-statement = 'repeat' statement-sequence 'until' boolean-expression
  4353.  
  4354. -------------------
  4355. 9.9 While Statement
  4356. -------------------
  4357. While statements are used to repeatedly execute a statement in a loop.
  4358. While statements contain a statement and a loop condition. When a while
  4359. statement is executed the statement is executed as long as the loop condition
  4360. is satisfied. The loop condition is tested before the statement is executed
  4361. so it is possible that the statement not be executed at all. The loop
  4362. condition is a boolean expression and is satisfied as long as the expression
  4363. evaluates to true. Usually the statement will perform some action that will
  4364. eventually cause the loop condition to fail and thus terminate the loop. It
  4365. is also possible to use a goto statement to terminate the loop.
  4366.  
  4367. For example below is a very simple program which illustrates the use
  4368. of the while statement.
  4369.  
  4370.    program ten(output);
  4371.    var
  4372.       count : 1..11;
  4373.    begin
  4374.       count := 1;
  4375.       while count <= 10 do
  4376.      begin
  4377.        writeln(count);
  4378.        count := count + 1;
  4379.      end
  4380.    end.
  4381.  
  4382. The syntax for while statements is given below
  4383.  
  4384.   while-statement = 'while' boolean-expression 'do' statement
  4385.  
  4386. ------------------
  4387. 9.10 For Statement
  4388. ------------------
  4389. For statements are used to repeatedly execute a statement in a loop, while
  4390. at the same time counting each loop iteration. For statements contain a
  4391. control variable, an initial value, a final value, and a statement.
  4392. There are two kind of for statements, one kind counts upwards, and the
  4393. other kind counts downwards.
  4394.  
  4395. For statements that count upwards are executed as follows:
  4396. First initial value is compared with the final value, and if the initial
  4397. value is greater than the final value then the execution of the for
  4398. statement is terminated immediately and the statement contained in the
  4399. for statement is never executed. If the initial value is not greater than
  4400. the final value then the initial value is assigned to the control variable
  4401. and the looping begins. For each iteration of the loop the statement
  4402. contained in the for statement is executed and then the control variable
  4403. is incremented by one. The loop continues as long as the control variable
  4404. is less than or equal to the final value.
  4405.  
  4406. For statements that count downwards are executed as follows:
  4407. First initial value is compared with the final value, and if the initial
  4408. value is less than the final value then the execution of the for
  4409. statement is terminated immediately and the statement contained in the
  4410. for statement is never executed. If the initial value is not less than
  4411. the final value then the initial value is assigned to the control variable
  4412. and the looping begins. For each iteration of the loop the statement
  4413. contained in the for statement is executed and then the control variable
  4414. is decremented by one. The loop continues as long as the control variable
  4415. is greater than or equal to the final value.
  4416.  
  4417. You should not depend on the control variable having any particular value
  4418. after execution of a for statement unless the for statement was left
  4419. using a goto statement.
  4420.  
  4421. Normally when executing a for statement it is best if the value of the
  4422. control variable is changed only by the for statement. If another statement
  4423. alters the value of the control variable it usually means that there is
  4424. a bug somewhere in your program. In an apparent effort to protect
  4425. programmers from making that kind of mistake Standard (ISO/IEC 7185) Pascal
  4426. defines a number of rules that restrict how control variables are used.
  4427. Irie Pascal implements these rules.
  4428.  
  4429. The first rule is that control variables must be declared at the same
  4430. level as the for statement (i.e. if the for statement is in a function or
  4431. procedure then the control variable must be local to that function or
  4432. procedure, and if the for statement is in the main program block then the
  4433. control variable must be global). Keeping the control variable local
  4434. makes it easier to control access.
  4435.  
  4436. The second rule is that neither the for statement nor any function or
  4437. procedure local to the block containing the for statement shall contain
  4438. a statement that "threatens" the control variable.
  4439. A statement "threatens" the control variable if the execution of the
  4440. statement could possibly alter the control variable.
  4441. So for example
  4442.   An assignment statement "threatens" the control variable if the control
  4443.   variable is the variable being assigned to.
  4444.  
  4445.   A function or procedure call "threatens" the control variable if the
  4446.   control variable is being passed by reference.
  4447.  
  4448.   A "read" or "readln" statement "threatens" the control variable is
  4449.   used in the read-parameter-list or the readln-parameter-list.
  4450.   
  4451.   A for statement "threatens" the control variable if it uses the
  4452.   same control variable.
  4453.  
  4454. The syntax for the for statement is given below:
  4455.  
  4456.    for-statement =
  4457.      'for' control-variable ':=' initial-value ('to' | 'downto') final-value
  4458.      'do' statement
  4459.  
  4460.    control-variable = variable-identifier
  4461.  
  4462.    initial-value = ordinal-expression
  4463.  
  4464.    final-value = ordinal-expression
  4465.  
  4466. -------------------
  4467. 9.11 With Statement
  4468. -------------------
  4469. With statements allow the fields of a record variable to be accessed
  4470. without specifying the record-variable each time. With statements contain
  4471. a record variable list and a statement. When a with statement is executed
  4472. the statement it contains is executed, however the fields in the record
  4473. variable can be accessed using the field identifier alone.
  4474.  
  4475. For example give the following type and variable
  4476.  
  4477.    type
  4478.      student = record
  4479.      name : string;
  4480.      address : string;
  4481.      grade : integer;
  4482.      end;
  4483.  
  4484.    var
  4485.      s : student;
  4486.  
  4487. then
  4488.  
  4489.    with s do
  4490.       begin
  4491.      name := 'John';
  4492.      address := 'main street';
  4493.      grade := 20;
  4494.       end
  4495.  
  4496. is equivalent to
  4497.  
  4498.    begin
  4499.       s.name := 'John';
  4500.       s.address := 'main street';
  4501.       s.grade := 20;
  4502.    end
  4503.  
  4504. Since some record types can contain other record types
  4505. you can have nested with statements like
  4506.  
  4507.    with record1 do
  4508.       with record2 do
  4509.     with record3 do
  4510.         statement
  4511.  
  4512. or you can use the following shorthand
  4513.  
  4514.   with record1, record2, record3 do
  4515.      statement
  4516.  
  4517. The syntax for the with statement is given below:
  4518.  
  4519.    with-statement = 'with' record-variable-list 'do' statement
  4520.  
  4521.    record-variable-list = record-variable { ';' record-variable }
  4522.  
  4523. ---------------------
  4524. 10 Program parameters
  4525. ---------------------
  4526. Program parameters are identifiers which appear after the program name
  4527. (placed between parentheses). In addition to appearing after the program
  4528. name, most program parameters must also appear in a global variable
  4529. declaration. Two special program parameters "input" and "output" are
  4530. the exceptions to this rule. The appearance of the two special program
  4531. parameters, after the program name, automatically declares them as two
  4532. special file variables which reference the standard-input and
  4533. standard-output streams.
  4534.  
  4535. You can use program parameters to access command-line arguments passed to
  4536. your program (see also extended procedures "paramcount" and "paramstr"). For
  4537. example suppose you want to write a program to append two files together,
  4538. writing the appended files to a third file, then you might write a program
  4539. similar to the sample program below.
  4540.  
  4541.    (**********************************************************************
  4542.    ** This program appends two files together, writing the appended files
  4543.    ** out to a third file.
  4544.    *)
  4545.    program append(in1, in2, out, output);
  4546.    type
  4547.       char_file = file of char;
  4548.    var
  4549.       in1 : char_file;     (* first input file *)
  4550.       in2 : char_file;     (* second input file *)
  4551.       out : char_file;     (* output file *)
  4552.  
  4553.       (***************************************************************
  4554.       ** PURPOSE: Writes copies the contents of one file into another.
  4555.       ** ARGUMENTS:
  4556.       **    'f' - the input file
  4557.       **    'g' - the output file
  4558.       ** NOTES: It is up to the caller to open and close the files.
  4559.       *)
  4560.       procedure WriteFile(var f, g: char_file);
  4561.       var
  4562.      c : char;
  4563.       begin
  4564.      while not eof(f) do
  4565.         begin
  4566.            read(f, c);
  4567.            write(g, c)
  4568.         end
  4569.       end;
  4570.  
  4571.       (**********************************************
  4572.       ** PURPOSE: Writes a help screen and then halts
  4573.       *)
  4574.       procedure syntax;
  4575.       begin
  4576.      writeln('Appends two files together and writes the output to a third file');
  4577.      writeln('Syntax');
  4578.      writeln('   ivm append in1 in2 out');
  4579.      writeln('where "in1" is the first input file');
  4580.      writeln('and   "in2" is the second input file');
  4581.      writeln('and   "out" is the output file');
  4582.      halt
  4583.       end;
  4584.  
  4585.    begin
  4586.       if paramcount <> 3 then
  4587.      syntax;
  4588.       rewrite(out);
  4589.       reset(in1);
  4590.       WriteFile(in1, out);
  4591.       close(in1);
  4592.       reset(in2);
  4593.       WriteFile(in2, out);
  4594.       close(in2)
  4595.       close(out);
  4596.    end.
  4597.  
  4598. The first thing to notice about this program is the line below:
  4599.  
  4600.    program append(in1, in2, out, output);
  4601.  
  4602. Here four program parameters are being used "in1", "in2", "out", and "output".
  4603. The first program parameter "in1" accesses the first command-line argument
  4604. The second program parameter "in2" accesses the second command-line argument.
  4605. The third program parameter "out" accesses the third command-line argument.
  4606. The fourth program parameter "output" declares the special file variable
  4607. which references the standard-output stream, and has nothing to do with
  4608. command-line arguments. "output" does not have to be the last program
  4609. parameter, it can be used in the first, or second or any position. Since
  4610. "output" does not access any command-line arguments it can appear in any
  4611. position (not just the fourth and last position) without disturbing the
  4612. command-line arguments accessed by the other program parameters. In other
  4613. words all of the following are equivalent
  4614.  
  4615.    program append(output, in1, in2, out);
  4616. or
  4617.    program append(in1, output, in2, out);
  4618. or
  4619.    program append(in1, in2, output, out);
  4620. or
  4621.    program append(in1, in2, out, output);
  4622.  
  4623. And in each of the four cases "in1" accesses the first command-line argument
  4624. and "in2" accesses the second command-line argument
  4625. and "out" accesses the third command-line argument.
  4626.  
  4627. The second thing to notice about the program are the following lines.
  4628.  
  4629.    var
  4630.       in1 : char_file;     (* first input file *)
  4631.       in2 : char_file;     (* second input file *)
  4632.       out : char_file;     (* output file *)
  4633.  
  4634. Here the program parameters (except for "output") appear in global variable
  4635. declarations as required. They are declared to be variables of type
  4636. "char_file" which has been declared to be "file of char". Now since they are
  4637. declared to be file variables it means that the command-line arguments
  4638. accessed specify the names of the external files associated with the file
  4639. variables. What this means is that if the file variables are opened (using
  4640. "reset", "rewrite", or "append") then the external file which is opened is
  4641. the one specified by the command-line argument accessed.
  4642. For example if the program is run with the line
  4643.  
  4644.    ivm append x.txt y.txt a:\z.txt
  4645.  
  4646. then when "in1" is opened the file "x.txt" is opened
  4647. and when "in2" is opened the file "y.txt" is opened
  4648. and when "out" is opened the file "a:\z.txt" is opened.
  4649.  
  4650. The final thing to notice about the program are the following lines.
  4651.  
  4652.       if paramcount <> 3 then
  4653.      syntax;
  4654.  
  4655. These lines cause the procedure "syntax" to be called if the number of
  4656. command-line arguments is not 3. These lines are intended to prevent
  4657. problems if the user does not enter 3 command-line arguments.
  4658.  
  4659. Suppose for example that this program was run with no command-line arguments.
  4660. The first program argument "in1" will access the first command-line argument
  4661. which does not exist so the empty string will specify the external file
  4662. associated with this file variable. Similarly the empty string will specify
  4663. the external files associated with the file variables "in2" and "out".
  4664.  
  4665. You might ask what happens if you open a file variable associated with an
  4666. external file specified by an empty string? Well, if you open such a
  4667. file variable for reading (with "reset") then the external file opened
  4668. is the standard input stream. If you open such a file for writing
  4669. (with "rewrite" or "append") then the external file opened is the standard
  4670. output stream.
  4671.  
  4672. I didn't want this effect when I wrote the sample program above so I
  4673. inserted the lines
  4674.  
  4675.       if paramcount <> 3 then
  4676.      syntax;
  4677.  
  4678. to avoid this.
  4679.  
  4680. So far I have described how file-type program parameters are handled.
  4681. You can also use string-type program parameters. They also access the
  4682. command-line arguments, but in a different way. The command-line
  4683. argument accessed is simply assigned to the string-type program parameter.
  4684.  
  4685. If you use program parameters other than file-type or string-type then
  4686. the command-line argument is ignored. The compiler will issue a warning,
  4687. that the command-line argument has an invalid type, but otherwise do
  4688. nothing.
  4689.  
  4690. For example look at this rather strange program.
  4691.  
  4692.    program strange(f, s1, dummy, s2);
  4693.    var
  4694.       f : text;
  4695.       s1, s2 : string;
  4696.       dummy : real;
  4697.    begin
  4698.       rewrite(f);
  4699.       writeln(f, s1);
  4700.       writeln(f, s2)
  4701.    end.
  4702.  
  4703. If you compile it you will get some warnings but ignore them.
  4704. If you run the program with
  4705.  
  4706.    ivm strange out.txt first skip second
  4707.  
  4708. then the first program parameter "f" will access "out.txt", and since
  4709. "f" is a file-type program argument when "rewrite" is used on "f" the
  4710. file "out.txt" will be opened for writing.
  4711. The second program parameter "s1" will access "first", and since this
  4712. is a string-type program argument then "first" will be assigned to "s1".
  4713. The third program parameter "dummy" is not a file-type or string-type
  4714. program parameter so the third command-line argument "skip" will be
  4715. ignored.
  4716. The fourth program parameter "s2" will access "second", and since this
  4717. is a string-type program argument then "second" will be assigned to "s2".
  4718.  
  4719. So the effect of the following three lines
  4720.  
  4721.       rewrite(f);
  4722.       writeln(f, s1);
  4723.       writeln(f, s2)
  4724.  
  4725. is that a text file "out.txt" is opened and two lines are written to it.
  4726. The first line will be "first" and the second will be "second".
  4727.  
  4728. -------------------------------
  4729. Appendix A. Irie Pascal Grammar
  4730. -------------------------------
  4731. The start symbol for this grammar is "program".
  4732.  
  4733.    actual-parameter = expression |
  4734.               variable-access |
  4735.               procedure-identifier |
  4736.               function-identifier
  4737.               omitted-parameter
  4738.  
  4739.    actual-parameter-list = '(' actual-parameter { ',' actual-parameter } ')'
  4740.  
  4741.    adding-operator = '+' | '-' | 'or' | 'or_else' | 'xor'
  4742.  
  4743.    array-type = 'array' '[' index-type-list ']' 'of' component-type
  4744.  
  4745.    assignment-statement = variable-access ':=' expression
  4746.  
  4747.    block = declarative-part statement-part
  4748.  
  4749.    buffer-variable = file-variable '^' | file-variable '@'
  4750.  
  4751.    case-body = case-list-elements [ [ ';' ] case-statement-completer ] |
  4752.            case-statement-completer
  4753.  
  4754.    case-constant = ordinal-constant
  4755.  
  4756.    case-constant-list = case-specifier { ',' case-specifier }
  4757.  
  4758.    case-index = ordinal-expression
  4759.  
  4760.    case-list-element = case-constant-list ':' statement
  4761.  
  4762.    case-list-elements = case-list-element { ';' case-list-element }
  4763.  
  4764.    case-specifier = case-constant [ '..' case-constant ]
  4765.  
  4766.    case-statement = 'case' case-index case-body [ ';' ] 'end'
  4767.  
  4768.    case-statement-completer = 'otherwise' statement-sequence
  4769.  
  4770.    component-type = type-denoter
  4771.  
  4772.    component-variable = indexed-variable | field-designator
  4773.  
  4774.    compound-statement = 'begin' statement-sequence 'end'
  4775.  
  4776.    conditional-statement = if-statement |
  4777.                case-statement
  4778.  
  4779.    constant = integer | real | character-literal | string-literal |
  4780.           constant-identifier
  4781.  
  4782.    constant-declaration = identifier '=' constant
  4783.  
  4784.    constant-declaration-group =
  4785.      'const' constant-declaration ';' { constant-declaration ';' }
  4786.  
  4787.    control-variable = variable-identifier
  4788.  
  4789.    declarative-part = { pre-declaration } { sub-block-declaration }
  4790.  
  4791.    domain-type = type-identifier
  4792.  
  4793.    else-part = 'else' statement
  4794.  
  4795.    empty-statement =
  4796.  
  4797.    entire-variable = variable-identifier
  4798.  
  4799.    expression = shift-expression [ relational-operator shift-expression]
  4800.  
  4801.    factor = [sign] unsigned-constant |
  4802.         [sign] variable-access |
  4803.         [sign] '(' expression ')' |
  4804.         function-designator |
  4805.         'not' factor |
  4806.         set-constructor
  4807.  
  4808.    field-designator = record-variable '.' field-specifier |
  4809.               field-designator-identifier
  4810.  
  4811.    field-designator-identifier = identifier
  4812.  
  4813.    field-list = fixed-part ';' variant-part [ ';' ] |
  4814.      fixed-part [ ';' ] |
  4815.      variant-part [ ';' ] |
  4816.      empty
  4817.  
  4818.    field-specifier = field-identifier
  4819.  
  4820.    file-type = 'file' 'of' component-type
  4821.  
  4822.    final-value = ordinal-expression
  4823.  
  4824.    fixed-part = record-section { ';' record-section }
  4825.  
  4826.    for-statement =
  4827.      'for' control-variable ':=' initial-value ('to' | 'downto') final-value
  4828.      'do' statement
  4829.  
  4830.    function-designator = function-identifier [ actual-parameter-list ]
  4831.  
  4832.    goto-statement = 'goto' label
  4833.  
  4834.    identified-variable = pointer-variable '^' | pointer-variable '@'
  4835.  
  4836.    identifier-list = identifier { ',' identifier }
  4837.  
  4838.    if-statement = 'if' boolean-expression then-part [ else-part ]
  4839.  
  4840.    indexed-variable =
  4841.       array-variable '[' index-expression { ',' index-expression } ']'
  4842.  
  4843.    index-type = ordinal-type
  4844.  
  4845.    index-type-list = index-type { ',' index-type }
  4846.  
  4847.    initial-value = ordinal-expression
  4848.  
  4849.    label = digit-sequence | identifier
  4850.  
  4851.    label-declaration-group = 'label' label { ',' label } ';'
  4852.  
  4853.    list-type = 'list' 'of' component-type
  4854.  
  4855.    member-designator = expression [ '..' expression ]
  4856.  
  4857.    multiplying-operator = '*' | '/' | 'div' | 'mod' | 'and' | 'and_then'
  4858.  
  4859.    new-ordinal-type = enumerated-type | subrange-type
  4860.  
  4861.    new-pointer-type = '^' domain-type |
  4862.               '@' domain-type
  4863.  
  4864.    new-structured-type = [ 'packed' ] array-type |
  4865.              [ 'packed' ] record-type |
  4866.              [ 'packed' ] set-type |
  4867.              [ 'packed' ] file-type |
  4868.              [ 'packed' ] list-type |
  4869.                       string-type
  4870.  
  4871.    new-type = new-ordinal-type | new-structured-type | new-pointer-type
  4872.  
  4873.    omitted-parameter =
  4874.  
  4875.    ordinal-type = new-ordinal-type | ordinal-type-identifier
  4876.  
  4877.    pre-declaration = label-declaration-group |
  4878.              constant-declaration-group |
  4879.              type-declaration-group |
  4880.              variable-declaration-group
  4881.  
  4882.    procedure-identifier = identifier
  4883.  
  4884.    procedure-statement = procedure-identifier
  4885.    (
  4886.        [ actual-parameter-list ] |
  4887.        read-parameter-list |
  4888.        readln-parameter-list |
  4889.        write-parameter-list |
  4890.        writeln-parameter-list
  4891.    )
  4892.  
  4893.    program = 'program' program-name [ '(' program-args ')' ] ';' block '.'
  4894.  
  4895.    program-args = identifier-list
  4896.  
  4897.    read-parameter-list =
  4898.      '(' [ file-variable ',' ] variable-access { ',' variable-access } ')'
  4899.  
  4900.    readln-parameter-list =
  4901.      [ '(' ( file-variable | variable-access ) { ',' variable-access } ')' ]
  4902.  
  4903.    record-section = identifier-list ':' type-denoter
  4904.  
  4905.    record-type = 'record' field-list 'end'
  4906.  
  4907.    record-variable-list = record-variable { ';' record-variable }
  4908.  
  4909.    relational-operator = '=' | '<>' | '<' | '<=' | '>' | '>=' | 'in'
  4910.  
  4911.    repeat-statement = 'repeat' statement-sequence 'until' boolean-expression
  4912.  
  4913.    repetitive-statement = repeat-statement |
  4914.               while-statement |
  4915.               for-statement
  4916.  
  4917.    set-constructor = '[' [ member-designator { ',' member-designator } ] ']'
  4918.  
  4919.    set-type = 'set' 'of' ordinal-type
  4920.  
  4921.    shift-expression = simple-expression [ shift-operator simple-expression]
  4922.  
  4923.    shift-operator = 'shl' | shr'
  4924.  
  4925.    sign = '+' | '-'
  4926.  
  4927.    simple-expression = term { adding-operator term }
  4928.  
  4929.    simple-statement = empty-statement |
  4930.               assignment-statement |
  4931.               procedure-statement |
  4932.               goto-statement
  4933.  
  4934.    size = integer
  4935.  
  4936.    statement = [ label ':' ] ( simple-statement | structured-statement )
  4937.  
  4938.    statement-part = compound-statement
  4939.  
  4940.    statement-sequence = statement { ';' statement }
  4941.  
  4942.    string-type = 'string' |
  4943.          'string' '[' size ']' |
  4944.          'string' '(' size ')'
  4945.  
  4946.    structured-statement = compound-statement |
  4947.               conditional-statement |
  4948.               repetitive-statement |
  4949.               with-statement
  4950.  
  4951.    term = factor { multiplying-operator factor }
  4952.  
  4953.    then-part = 'then' statement
  4954.  
  4955.    type-declaration = identifier '=' type-denoter
  4956.  
  4957.    type-declaration-group =
  4958.     'type' identifier '=' type-declaration ';' { type-declaration ';' }
  4959.  
  4960.    type-denoter = type-identifier | new-type
  4961.  
  4962.    type-identifier = identifier
  4963.  
  4964.    unsigned-constant = unsigned-integer |
  4965.                unsigned-real |
  4966.                character-string |
  4967.                constant-identifier |
  4968.                'nil'
  4969.  
  4970.    variable-access = entire-variable |
  4971.              component-variable |
  4972.              identified-variable |
  4973.              buffer-variable
  4974.  
  4975.    variable-declaration = identifier-list ':' type-denoter
  4976.  
  4977.    variable-declaration-group =
  4978.       'var' variable-declaration { ';' variable-declaration }
  4979.  
  4980.    variant = case-constant-list ':' '(' field-list ')'
  4981.  
  4982.    variant-body = variant-list [ [;] variant-part-completer ] |
  4983.           variant-part-completer
  4984.  
  4985.    variant-list = variant { ';' variant }
  4986.  
  4987.    variant-part = 'case' variant-selector 'of' variant-body
  4988.  
  4989.    variant-part-completer = 'otherwise' '(' field-list ')'
  4990.  
  4991.    variant-selector = [ identifier ':' ] ordinal-type-identifier
  4992.  
  4993.    while-statement = 'while' boolean-expression 'do' statement
  4994.  
  4995.    with-statement = 'with' record-variable-list 'do' statement
  4996.  
  4997.    writeln-parameter-list =
  4998.      [ '(' ( file-variable | write-parameter ) { ',' write-parameter } ')' ]
  4999.  
  5000.    write-parameter = expression [ ':' expression [ ':' expression ] ]
  5001.  
  5002.    write-parameter-list =
  5003.      '(' [ file-variable ',' ] write-parameter { ',' write-parameter } ')'
  5004.  
  5005. -------------------------------------------------------------
  5006. Appendix B. Extensions to Pascal as specified by ISO/IEC 7185
  5007. -------------------------------------------------------------
  5008. Irie Pascal supports a number of extensions to Standard Pascal.
  5009. Some of these extensions were added for compatibility with Turbo Pascal and
  5010. Extended Pascal, while others were added because I thought they might be
  5011. useful.
  5012.  
  5013. Extensions can be enabled/disabled using the -E compiler option.
  5014.  
  5015. ------------------------
  5016. B.1 Relaxed declarations
  5017. ------------------------
  5018. Standard Pascal requires that all declarations/definitions of the same
  5019. kind must be made together in a single group and that the groups must
  5020. appear in a specific order. The order required by Standard Pascal is:
  5021.    Label declaration group
  5022.    Constant definition group
  5023.    Type definition group
  5024.    Variable declaration group
  5025.    sub-block declaration group
  5026.  
  5027. When "relaxed declarations" is enabled there can be more than one of each
  5028. kind of group and groups can appear in any order except that the
  5029. sub-block declaration group must be last.
  5030.  
  5031. So if "relaxed declarations" is enabled then the following program is legal,
  5032.  
  5033.    program summing(output);
  5034.    const
  5035.       first = 1;
  5036.       last = 100;
  5037.    type
  5038.       num = first..last;
  5039.    var
  5040.       i : num;
  5041.    type
  5042.       atype = array[first..last] of integer;
  5043.    var
  5044.       a : atype;
  5045.       sum : integer;
  5046.    begin
  5047.       sum := 0;
  5048.       for i := first to last do
  5049.      begin
  5050.         sum := sum + i;
  5051.         a[i] := sum
  5052.      end;
  5053.       for i := last downto first do
  5054.      writeln(i, a[i]);
  5055.    end.
  5056.  
  5057. even though it has two type definition groups
  5058.   "type num = first..last;"
  5059. and
  5060.   "type atype = array[first..last] of integer;"
  5061. and two variable declaration groups
  5062.   "var i : num;"
  5063. and
  5064.   "var a : atype; sum : integer;"
  5065.  
  5066. In Standard Pascal or with "relaxed declarations" disabled you would have to
  5067. combine these groups so you would have the following
  5068.  
  5069.    program summing(output);
  5070.    const
  5071.       first = 1;
  5072.       last = 100;
  5073.    type
  5074.       num = first..last;
  5075.       atype = array[first..last] of integer;
  5076.    var
  5077.       i : num;
  5078.       a : atype;
  5079.       sum : integer;
  5080.    begin
  5081.       sum := 0;
  5082.       for i := first to last do
  5083.      begin
  5084.         sum := sum + i;
  5085.         a[i] := sum
  5086.      end;
  5087.       for i := last downto first do
  5088.      writeln(i, a[i]);
  5089.    end.
  5090.  
  5091. -------------------
  5092. B.2 Constant ranges
  5093. -------------------
  5094. You can use constant ranges to specify a number of consecutive case
  5095. constants.
  5096. To use a constant range you specify the first constant, and the last
  5097. constant, separated by '..' as follows:
  5098.    first..last
  5099.  
  5100. You could use the constant range
  5101.    1..5
  5102. to specify the following constants
  5103.    1, 2, 3, 4, 5
  5104.  
  5105. For example suppose "c" is a char variable and you want to use a
  5106. case statement to write the word "Letter" if "c" contains a letter, and
  5107. the word "Digit" if "c" contains a digit, then you could specify each
  5108. constant individually as follows:
  5109.  
  5110.    case c of
  5111.       'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  5112.       'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  5113.       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  5114.       'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
  5115.      : write('Letter');
  5116.       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
  5117.      : write('Digit');
  5118.    end;
  5119.  
  5120. Or you could use constant ranges like the following:
  5121.  
  5122.    case c of
  5123.       'a'..'z', 'A'..'Z'
  5124.      : write('Letter');
  5125.       '0'..'9'
  5126.      : write('Digit');
  5127.    end;
  5128.  
  5129. Constant ranges can be used in case statements, like in the example above, 
  5130. and in variant records.
  5131.   
  5132. -------------
  5133. B.3 Otherwise
  5134. -------------
  5135. You can use the keyword "otherwise" in case statements and variant records
  5136. to specify "all values that haven't been used yet". You can also use
  5137. "else" instead of "otherwise" (this feature was added in order to improve
  5138. compatibility with Turbo Pascal).
  5139.  
  5140. For example in the following variant record
  5141.  
  5142.    type
  5143.       character = record
  5144.      case c : char of
  5145.      'a'..'z', 'A'..'Z'
  5146.         : (vowel : Boolean);
  5147.      '0'..'9'
  5148.         : (value : integer);
  5149.      otherwise
  5150.         ();
  5151.       end;
  5152.  
  5153. when "otherwise" is used, the following values have already been specified
  5154.    'a'..'z', 'A'..'Z', and '0'..'9'
  5155. so otherwise specifies all character values except
  5156.    'a'..'z', 'A'..'Z', and '0'..'9'
  5157.  
  5158. ------------------------------------
  5159. B.4 Relaxed parameter list congruity
  5160. ------------------------------------
  5161. Standard Pascal says the following parameter lists
  5162.    (VAR a, b : integer)
  5163. and
  5164.    (VAR c : integer; VAR d : integer)
  5165. are not congruous even though the individual parameters are congruous
  5166. because Standard Pascal compares formal parameter sections.
  5167. So in the example above the parameter lists are not congruous for two
  5168. reasons:
  5169. 1) The first parameter list has one formal parameter section
  5170.       "VAR a, b : integer"
  5171.    while the second parameter list has two formal parameter section
  5172.       "VAR c : integer" and "VAR d : integer"
  5173. 2) The individual parameter sections are not congruous
  5174.   (i.e.. "VAR a, b : integer" is not congruous with "VAR c : integer")
  5175.  
  5176. Irie Pascal checks for parameter list congruity by comparing the
  5177. individual parameters without regard to the formal-parameter-sections.
  5178. So the example above would be considered congruous since
  5179.    "a" and "c" are both integer variable parameters
  5180. and
  5181.    "b" and "d" are both integer variable parameters
  5182.  
  5183. Parameter list congruity becomes important when passing functions/procedures
  5184. since the parameter list of the actual function/procedure parameter must be
  5185. congruous with the parameter list of the corresponding formal
  5186. function/procedure parameter.
  5187.  
  5188. Relaxed parameter list congruity can not be disabled.
  5189.  
  5190. --------------------------------
  5191. B.5 Non-numeric statement labels
  5192. --------------------------------
  5193. Irie Pascal supports non-numeric statement labels.
  5194.  
  5195. For example in the following program "loop" is used as a statement label.
  5196.  
  5197.    program name(output);
  5198.    label loop;
  5199.    var
  5200.    i : integer;
  5201.    begin
  5202.       i := 1;
  5203.       loop:
  5204.       writeln(i);
  5205.       i := i + 1;
  5206.       if i <= 20 then goto loop;
  5207.    end.
  5208.  
  5209. ------------------------------
  5210. B.6 Underscores in identifiers
  5211. ------------------------------
  5212. Irie Pascal supports identifiers which contain and/or start with
  5213. underscores ("_").
  5214.  
  5215. ----------------------------
  5216. B.7 Binary integer constants
  5217. ----------------------------
  5218. Binary integer constants begin with "%", and are followed by one or
  5219. more binary digits.
  5220.  
  5221. The following are examples of valid binary constants
  5222.    %0   %1      %01110101010101010111101
  5223.  
  5224. The following are not valid binary constants
  5225.    %2    %      %151       %g
  5226.  
  5227. ---------------------------------
  5228. B.8 Hexadecimal integer constants
  5229. ---------------------------------
  5230. Hexadecimal integer constants begin with "$", and are followed by one or
  5231. more hexadecimal digits.
  5232.  
  5233. The following are examples of valid hexadecimal integer constants
  5234.    $9   $A123      $ffff
  5235.  
  5236. The following is not a valid hexadecimal integer constant
  5237.    $abgd
  5238. since "g" is not a hexadecimal integer constants.
  5239.  
  5240. -------------------------------------------
  5241. B.9 Input and Output automatically declared
  5242. -------------------------------------------
  5243. Standard (ISO/IEC 7185) Pascal specifies that whenever the required
  5244. identifiers "Input" and "Output" are referenced in a program that they
  5245. must by declared (i.e. appear as program parameters). However because
  5246. some Pascal compilers do not enforce this requirement many Pascal programs
  5247. do not meet this specification. In order to allow Irie Pascal to compile
  5248. these programs without requiring the user to insert "Input" and "Output"
  5249. into the program parameter list, I decided that by default Irie Pascal
  5250. should automatically declare Input and Output.
  5251.  
  5252. ---------------------------
  5253. B.10 Double-quoted literals
  5254. ---------------------------
  5255. You can use double quotation marks to form character and string literals.
  5256.  
  5257. For example you could use
  5258.    "Hello world"
  5259. instead of
  5260.    'Hello world'
  5261.  
  5262. Double-quoted literals can be useful if you want to create literals with
  5263. single quotes in them since you don't have to use two single quotes to
  5264. represent one single quote.
  5265.  
  5266. For example you could use
  5267.    "Don't go away"
  5268. which is equivalent to
  5269.    'Don''t do away'
  5270.  
  5271. ----------------------
  5272. B.11 and_then operator
  5273. ----------------------
  5274. The "and_then" operator is similar to the "and" operator except that
  5275. short-circuit evaluation is always used for "and_then" regardless of
  5276. the setting of the "sc" compiler option.
  5277.  
  5278. See "8.1.7 And_Then Operator" for more information.
  5279.  
  5280. ---------------------
  5281. B.12 or_else operator
  5282. ---------------------
  5283. The "or_else" operator is similar to the "or" operator except that
  5284. short-circuit evaluation is always used for "or_else" regardless of
  5285. the setting of the "sc" compiler option.
  5286.  
  5287. See "8.1.11 Or_Else Operator" for more information.
  5288.  
  5289. ----------------------
  5290. B.13 Bitwise operators
  5291. ----------------------
  5292. Irie Pascal defines several bitwise operators.
  5293.  
  5294. -------------------
  5295. B.13.1 shl operator
  5296. -------------------
  5297. The "shl" operator performs a left bit-shift, and returns the result of
  5298. this bit-shift. The left operand is the integer to be shifted, and the
  5299. right operand, which is also an integer, specifies the number of bits
  5300. to shift.
  5301.  
  5302. For example
  5303.     4 shl 2
  5304. is equal to 16,
  5305. since 4 shifted left by 2 bits is 16.
  5306.  
  5307. -------------------
  5308. B.13.2 shr operator
  5309. -------------------
  5310. The "shr" operator performs a right bit-shift, and returns the result of
  5311. this bit-shift. The left operand is the integer to be shifted, and the
  5312. right operand, which is also an integer, specifies the number of bits
  5313. to shift.
  5314.  
  5315. For example
  5316.     4 shr 2
  5317. is equal to 1, since 4 shifted right by 2 bits is 1.
  5318.  
  5319. -----------------------------
  5320. B.13.3 and (Bitwise) operator
  5321. -----------------------------
  5322. The bitwise "and" operator takes two integer operands and produces
  5323. an integer result. A bit in the result is 1 if the bit in the
  5324. corresponding position in the left operand is 1 AND the bit
  5325. in the corresponding position in the right operand is 1.
  5326. Otherwise the result bit is 0.
  5327.  
  5328. For example
  5329.    5 and 3 = 1
  5330. Since
  5331.       101    (which is 5 in binary)
  5332. and   011    (which is 3 in binary)
  5333. ---------
  5334.  =    001
  5335. ---------
  5336. NOTE: Bit zero is 1 in the result since bit zero is one in both
  5337. the left and right operands. All other bits are zero.
  5338.  
  5339. ----------------------------
  5340. B.13.4 or (Bitwise) operator
  5341. ----------------------------
  5342. The bitwise "or" operator takes two integer operands and produces
  5343. an integer result. A bit in the result is 1 if the bit in the
  5344. corresponding position in the left operand is 1 OR the bit
  5345. in the corresponding position in the right operand is 1 OR
  5346. both bits are 1.
  5347. Otherwise the result bit is 0.
  5348.  
  5349. For example
  5350.    5 or 3 = 7
  5351. Since
  5352.       101    (which is 5 in binary)
  5353. or    011    (which is 3 in binary)
  5354. ---------
  5355.  =    111
  5356. ---------
  5357.  
  5358. -----------------------------
  5359. B.13.5 not (Bitwise) operator
  5360. -----------------------------
  5361. The bitwise "not" operator takes an integer operand and produces
  5362. an integer result. A bit in the result is 1 if the bit in the
  5363. corresponding position in the operand is 0. A bit in the result
  5364. is 0 if the bit in the corresponding position in the operand is 1.
  5365.  
  5366. For example
  5367.    not 1 = -2
  5368. Since
  5369. not   00000000 00000000 00000000 00000001   = 1
  5370. -----------------------------------------
  5371.       11111111 11111111 11111111 11111110   = -2
  5372.  
  5373. -----------------------------
  5374. B.13.6 xor (Bitwise) operator
  5375. -----------------------------
  5376. The bitwise "xor" operator takes two integer operands and produces
  5377. an integer result. A bit in the result is 1 either the bit in the
  5378. corresponding position in the left operand is 1 OR the bit
  5379. in the corresponding position in the right operand is 1, but not
  5380. both. Otherwise the result bit is 0.
  5381.  
  5382. For example
  5383.    5 xor 3 = 6
  5384. Since
  5385.       101    (which is 5 in binary)
  5386. xor   011    (which is 3 in binary)
  5387. ---------
  5388.  =    110
  5389. ---------
  5390.  
  5391. -----------------------
  5392. B.14 Extended constants
  5393. -----------------------
  5394. Irie Pascal defines a number of built-in constants which are
  5395. not part of Standard Pascal. The constants are referred to
  5396. here as extended constants.
  5397.  
  5398. --------------
  5399. B.14.1 maxchar
  5400. --------------
  5401. Irie Pascal defines "maxchar" which is a built-in character constant,
  5402. whose value is the maximum character value allowed.
  5403.  
  5404. Syntax: maxchar
  5405.  
  5406. ------------
  5407. B.14.2 usr_r
  5408. ------------
  5409. Irie Pascal defines "usr_r" which is a built-in integer constant.
  5410. You can use this constant with the "mkdir" procedure to specify
  5411. that the directory owner has read permission.
  5412. You can also "or" this constant with a file mode to determine
  5413. if the file owner has read permission.
  5414.  
  5415. Syntax: usr_r
  5416.  
  5417. ------------
  5418. B.14.3 usr_w
  5419. ------------
  5420. Irie Pascal defines "usr_w" which is a built-in integer constant.
  5421. You can use this constant with the "mkdir" procedure to specify
  5422. that the directory owner has write permission.
  5423. You can also "or" this constant with a file mode to determine
  5424. if the file owner has write permission.
  5425.  
  5426. Syntax: usr_w
  5427.  
  5428. ------------
  5429. B.14.4 usr_x
  5430. ------------
  5431. Irie Pascal defines "usr_x" which is a built-in integer constant.
  5432. You can use this constant with the "mkdir" procedure to specify
  5433. that the directory owner has execute permission.
  5434. You can also "or" this constant with a file mode to determine
  5435. if the file owner has execute permission.
  5436.  
  5437. Syntax: usr_x
  5438.  
  5439. ------------
  5440. B.14.5 grp_r
  5441. ------------
  5442. Irie Pascal defines "grp_r" which is a built-in integer constant.
  5443. You can use this constant with the "mkdir" procedure to specify
  5444. that the directory owner's group has read permission.
  5445. You can also "or" this constant with a file mode to determine
  5446. if the file owner's group has read permission.
  5447.  
  5448. Syntax: grp_r
  5449.  
  5450. ------------
  5451. B.14.6 grp_w
  5452. ------------
  5453. Irie Pascal defines "grp_w" which is a built-in integer constant.
  5454. You can use this constant with the "mkdir" procedure to specify
  5455. that the directory owner's group has write permission.
  5456. You can also "or" this constant with a file mode to determine
  5457. if the file owner's group has write permission.
  5458.  
  5459. Syntax: grp_w
  5460.  
  5461. ------------
  5462. B.14.7 grp_x
  5463. ------------
  5464. Irie Pascal defines "grp_x" which is a built-in integer constant.
  5465. You can use this constant with the "mkdir" procedure to specify
  5466. that the directory owner's group has execute permission.
  5467. You can also "or" this constant with a file mode to determine
  5468. if the file owner's group has execute permission.
  5469.  
  5470. Syntax: grp_x
  5471.  
  5472. ------------
  5473. B.14.8 oth_r
  5474. ------------
  5475. Irie Pascal defines "oth_r" which is a built-in integer constant.
  5476. You can use this constant with the "mkdir" procedure to specify
  5477. that (the world) everyone has read permission.
  5478. You can also "or" this constant with a file mode to determine
  5479. if (the world) everyone has read permission.
  5480.  
  5481. Syntax: oth_r
  5482.  
  5483. ------------
  5484. B.14.9 oth_w
  5485. ------------
  5486. Irie Pascal defines "oth_w" which is a built-in integer constant.
  5487. You can use this constant with the "mkdir" procedure to specify
  5488. that (the world) everyone has write permission.
  5489. You can also "or" this constant with a file mode to determine
  5490. if (the world) everyone has write permission.
  5491.  
  5492. Syntax: oth_w
  5493.  
  5494. -------------
  5495. B.14.10 oth_x
  5496. -------------
  5497. Irie Pascal defines "oth_x" which is a built-in integer constant.
  5498. You can use this constant with the "mkdir" procedure to specify
  5499. that (the world) everyone has execute permission.
  5500. You can also "or" this constant with a file mode to determine
  5501. if (the world) everyone has execute permission.
  5502.  
  5503. Syntax: oth_x
  5504.  
  5505. ---------------
  5506. B.14.11 dir_bit
  5507. ---------------
  5508. Irie Pascal defines "dir_bit" which is a built-in integer constant.
  5509. You can "or" this constant with a file mode to determine if the
  5510. file is a directory.
  5511.  
  5512. Syntax: dir_bit
  5513.  
  5514. --------------------
  5515. B.14.12 platform_dos
  5516. --------------------
  5517. Irie Pascal defines "platform_dos" which is a built-in integer constant.
  5518. You can compare this constant with the value returned by the "platform"
  5519. function to determine if your program is running under dos.
  5520.  
  5521. --------------------
  5522. B.14.13 platform_os2
  5523. --------------------
  5524. Irie Pascal defines "platform_os2" which is a built-in integer constant.
  5525. You can compare this constant with the value returned by the "platform"
  5526. function to determine if your program is running under OS/2.
  5527.  
  5528. ----------------------
  5529. B.14.14 platform_win32
  5530. ----------------------
  5531. Irie Pascal defines "platform_win32" which is a built-in integer constant.
  5532. You can compare this constant with the value returned by the "platform"
  5533. function to determine if your program is running under WIN32.
  5534.  
  5535. ----------------------
  5536. B.14.15 platform_linux
  5537. ----------------------
  5538. Irie Pascal defines "platform_linux" which is a built-in integer constant.
  5539. You can compare this constant with the value returned by the "platform"
  5540. function to determine if your program is running under Linux.
  5541.  
  5542. ---------------------
  5543. B.14.16 platform_fbsd
  5544. ---------------------
  5545. Irie Pascal defines "platform_fbsd" which is a built-in integer constant.
  5546. You can compare this constant with the value returned by the "platform"
  5547. function to determine if your program is running under FreeBSD.
  5548.  
  5549. ----------------------
  5550. B.14.17 platform_error
  5551. ----------------------
  5552. Irie Pascal defines "platform_error" which is a built-in integer constant.
  5553. You can compare this constant with the value returned by the "platform"
  5554. function to determine if the call to "platform" failed.
  5555.  
  5556. ------------------
  5557. B.14.18 appendmode
  5558. ------------------
  5559. Irie Pascal defines "appendmode" which is a built-in integer constant.
  5560. You can use this constant with the "open" function to specify that the
  5561. file should be opened in append mode.
  5562.  
  5563. ----------------
  5564. B.14.19 readmode
  5565. ----------------
  5566. Irie Pascal defines "readmode" which is a built-in integer constant.
  5567. You can use this constant with the "open" function to specify that the
  5568. file should be opened for reading (i.e. input). You can combine
  5569. (with "+" or "or") this constant with "writemode" to specify that the
  5570. file should be opened for both reading and writing.
  5571.  
  5572. -----------------
  5573. B.14.20 writemode
  5574. -----------------
  5575. Irie Pascal defines "writemode" which is a built-in integer constant.
  5576. You can use this constant with the "open" function to specify that the
  5577. file should be opened for writing (i.e. output). You can combine
  5578. (with "+" or "or") this constant with "readmode" to specify that the
  5579. file should be opened for both reading and writing.
  5580.  
  5581. -------------------
  5582. B.15 Extended types
  5583. -------------------
  5584. Irie Pascal defines a number of extended types
  5585. (i.e. built-in types that are not a part of Standard Pascal).
  5586.  
  5587. ----------
  5588. B.15.1 dir
  5589. ----------
  5590. Irie Pascal defines a type identifier called "dir" which is the
  5591. type of directory variables, which are used in the
  5592. directory manipulation procedures.
  5593.  
  5594. See "7.2.6 closedir", "7.2.27 opendir", "7.2.35 readdir", and
  5595. "7.2.39 rewinddir".
  5596.  
  5597. ---------------
  5598. B.15.2 filename
  5599. ---------------
  5600. Irie Pascal defines a type identifier called "filename" which is the
  5601. string type most suitable for variables used to store filenames.
  5602.  
  5603. Syntax: filename
  5604.  
  5605. For example to declare a variable to store filenames use
  5606. var
  5607.    name : filename;
  5608.  
  5609. NOTE: You can also use string types such as
  5610. var
  5611.    name : packed array[1..N] of char;
  5612. or
  5613.    name : string;
  5614.  
  5615. But I recommend you use "filename" since this type is likely to be
  5616. the most suitable type for storing filenames.
  5617.  
  5618. -----------
  5619. B.15.3 list
  5620. -----------
  5621. Irie Pascal defines a new keyword "list" in order to provide support
  5622. for lists. To create a list type use the syntax below.
  5623.  
  5624. Syntax: [packed] list of Type
  5625. where
  5626.    "Type" is the type of the components in the list.
  5627.  
  5628. If you use "packed" then the list is likely to be more efficient in
  5629. terms of memory but less efficient in terms of speed.
  5630.  
  5631. You must use "new" to initialize a list variable before you use it.
  5632. The syntax is:
  5633.     new(list-variable)
  5634.  
  5635. You can use "dispose" to release the memory used by a list variable
  5636. after you have finished with it. The syntax is:
  5637.     dispose(list-variable)
  5638.  
  5639. You can use "insert" to add components to a list variable.
  5640.  
  5641. You can use "delete" to remove components from a list variable.
  5642.  
  5643. You can use the "length" function to determine the number of components in a
  5644. list variable.
  5645.  
  5646. You can access the components of a list variable just like an array
  5647. variable. The syntax is
  5648.      lv '[' p ']'
  5649. where
  5650.      "lv" is the list variable being accessed
  5651.      "p" is the position of the component being accessed
  5652. For example if "i" is an integer and "lv" is a list variable then the
  5653. statement below will write each component of "lv".
  5654.      for i := 1 to length(lv) do
  5655.     writeln(lv[i])
  5656.  
  5657. -------------
  5658. B.15.4 string
  5659. -------------
  5660. Standard Pascal considers packed arrays of char with a lower bound of 1 to
  5661. be strings. However these are fixed length strings (i.e.. the only text that
  5662. can be assigned to these strings is text of exactly the same length as the
  5663. length of the array).
  5664.  
  5665. Irie Pascal supports variable length strings using a new type "string".
  5666.  
  5667. For example to create a variable length string type called "name" with
  5668. a maximum length of 80 use
  5669.    name = string[80];
  5670. or
  5671.    name = string(80);
  5672.  
  5673. To create a variable length string type called "address" with a maximum length
  5674. of 255 use
  5675.    address = string;
  5676. or
  5677.    address = string[255];
  5678. or
  5679.    address = string(255);
  5680.  
  5681. The advantage of variable length strings is that any string can be assigned
  5682. to them, whether fixed or variable length, as long as the length of the
  5683. string being assigned does not exceed the string's maximum length.
  5684. Even characters can be assigned to variable length strings.
  5685.  
  5686. You can use the "+" operator to perform string concatenation.
  5687.  
  5688. -----------------------
  5689. B.16 Extended variables
  5690. -----------------------
  5691. Irie Pascal defines one extended variable
  5692. (i.e. a built-in variable that is not a part of Standard Pascal).
  5693.  
  5694. ---------------
  5695. B.16.1 exitcode
  5696. ---------------
  5697. Irie Pascal defines "exitcode" which is a built-in integer variable,
  5698. whose value is returned to the calling program when your program exits.
  5699.  
  5700. Syntax: exitcode
  5701.  
  5702. For example suppose you want to return a value of 1 from your program
  5703. (perhaps to indicate that your program detected an error) then you can
  5704. use the following code
  5705.  
  5706.    exitcode := 1;
  5707.    halt;
  5708.  
  5709. NOTE: You can treat "exitcode" like any other integer variable
  5710. (i.e. you can assign to it, use it in an expression, pass it as an
  5711. argument to a function, etc).
  5712.  
  5713. END
  5714.