Pascal Language Reference Manual Sep83
Pascal Language Reference Manual Sep83
_.
.
_.
.-------
__..
-.--:...
--
-
_.-
_ . . . .~-----
_
_ ____________ ...-------. ""T"
~ ~
_a. ----..
.. _.. --
....... -
__ a
_.-
_L-L
_.. _.
__ a -----.
_. _ . _. _
- I = = =. ~ ...........
----
~ ~
I = = !!! ~
s Y S T EMS
739 Allston Way. Berkeley. CA 94710
(415) 644-1230. TWX" 910 366-2145
UUCP ucbvaxlunisoftlunisoft
Pascal
Language Reference Manual
PN: 1020-04
UlliSol1
S Y S T EMS
This Pascal Reference Manual was produced by:
Preface
Chapter 1 - Introduction . . . . . 4
2.1 Overview of the Pascal Language 4
2.2 Metalanguage . . . . . • 8
2.3 Elementary Lexical Constructs 8
Chapter 2 - Defining Data Types 12
2.1 Defining Constants 12
2.2 Standard Types . . . . 13
2.3 Defining Data Types. 15
2.4 Simple Types . . . . 15
2.5 Structured Types . . 16
2.6 Pointer Types . . . . 22
2.7 Type Identity and Assignment Compatibility 23
Chapter 3 - Variables . . . 25
3.1 Declaring Variables . . 25
3.2 Predeclared Variables 26
3.3 Establishing Variables 26
3.4 Lifetimes of Variables 26
3.5 Referencing or Accessing Variables . 27
Chapter 4 - Expressions . . . . 31
4.1 Operators in Expressions • . . . 32
4.2 Address Evaluation Operator 32
4.3 NOT Operator. . . 32
4.4 Multiplying Operators 32
4.5 Adding Operators. . . 34
4.6 Sign Operators. . . 34
4.7 Relational Operators. . 35
4.8 Out of Range Values 37
4.9 Order of Evaluation in Expressions 38
4.1 0 Compile Time Constant Expressions 38
Chapter 5 - Statements . . . . 40
5.1 Statement Labels • . . . . . . 40
5.2 Assignment Statements. . . . 40
5.3 Procedure Reference Statement • • 41
5.4 Structured Statements 42
5.5 The WITH Statement 46
5.6 The GOTO Statement 47
Chapter 6 - Input and Output 49
6.1 General File Handling Procedures 49
6.2 Text File Handling Procedures 52
6.3 Block Input Output Intrinsics . 59
-i-
6.4 IORESUL T - Return Input-Output Result 61
Chapter 7 - Program Structure . . • • 63
7.1 Compilation Units . . . . • . 63
7.2 Declarations and Scope of Identifiers 68
7.3 Program Heading . • . . . . . . . . . . 69
7.4 Declarations . • . . • . . . . . 71
7.5 Procedure and Function Declaration 72
Chapter 8 - Standard Procedures and Functions 77
8.1 String Manipulation Facilities . 77
8.2 Storage Allocation Procedures 82
8.3 Arithmetic Functions . . . . 84
8.4 Predicates or Boolean Attributes . 86
8.5 Value Conversion Functions . . • • . 86
8.6 Other Standard Functions . . • 87
8.7 Miscellaneous Low Level Routines . 88
8.8 Control Procedures . . . . • 90
Chapter 9 - Pascal Compile Time Options 92
Appendix A - Messages from the Pascal System . 95
A.1 Compile Time Lexical Errors . 95
A.2 Compile Time Syntactic Errors, 95
A.3 Compile Time Semantic Errors 96
A.4 Specific Limitations of the Compiler . . • . 98
A.5 Input Output Errors . . • 98
A.6 Code Generation Errors •.•.. 99
A.7 IORESULT Error Codes . . • . 99
Appendix B - Pascal Language Summary . . . . • 100
B.1 Predefined Identifiers . . . . . 100
B.2 Pascal Syntax Definitions . . . . . 101
Appendix C - Relationships to ISO Pascal 108
Appendix D - Relationships to UCSD Pascal 110
D.1 Differences from UCSD Pascal 110
Appendix E - Data Representations • . • . 114
E.1 Storage Allocation .. . . . . • . . . . . . 114
E.2 Representation of Integers. . . • • . 115
E.3 Representation of Reals and Doubles 116
E.4 Representation of Extreme Numbers 117
E.5 Representation of Sets . . . . . . . 121
E.6 Representation of Arrays 121
E.7 Packing Methods . . . . . . . 122
E.8 Parameter Passing Mechanism . . . . 124
E.9 Register Conventions . • . . 125
E.10 Limitations On Size of Variables. 126
- ii -
E.ll Compiler Generated Linker Names. . . 126
Appendix F - Operating the SVS Pascal System 127
F.l System Components. . . . . . . . . 127
F.2 Command Line Directives and Compiler Options • 129
F.3 Linking Programs which Utilize C and FORTRAN 130
Appendix G - UNIX Operating System Specific
Information .....•..•.. 134
G.l Compiling a Simple Program . 134
G.2 Error Message File 135
G.3 Ulinker . . • . • . . • . 135
G.4 Linking to UNIX Assem bly Code 139
G.5 Argc and Argv. . . . • . . • . 140
G.6 Features not Implemented Under UNIX . 140
G.7 Return Values from Pascal Programs . . . • . 140
- iii -
Preface
Preface
The overall layout of this manual loosely follows that of the Pascal User
Manual and Report, by Kathleen Jensen and Niklaus Wirth. The phrase
"Jensen and Wirth" is used to refer to that book. There is somewhat more
detail in this reference manual than in Jensen and Wirth.
In general, the order that topics are presented in is: first some narrative
introductory material, then formal descriptions, followed by examples.
Chapter 1 - "Introduction" is an introduction to Pascal terms and
concepts. It contains an overview of the Pascal language. There is a description
of the metalanguage that this manual uses to describe the Pascal Language.
Finally there are descriptions of the basic elements of Pascal.
Chapter 2 - "Defining Data Types" introduces the concepts of data types
and discusses the notations by which data types are defined and declared.
Chapter 3 - "Variables" describes the means whereby variables are
declared and referenced.
Chapter 4 - "Expressions" describes Pascal expressions which are used to
derive new data values.
Chapter 5 - "Statements" presents Pascal statements and how they are
used to achieve computing actions.
Chapter 6 - "Input and Output" covers Pascal input and output facilities.
Chapter 7 - "Program Structure" describes Program Structure in Pascal,
including the ideas of independent compilation units.
Chapter 8 - "Standard Procedures and Functions" describes Pascal
standard procedures and functions, that is, those "built in" facilities of the
language that a user program need not provide.
Chapter 9 - "Pascal Compile Time Options" describes the compile time
options available to the programmer, in order to exercise control over some of
the actions of the Pascal compiler and the run time system.
Appendix A - "Messages from the Pascal System" is a list of diagnostic
messages from the Pascal compiler and the run-time library.
Appendix B - "Pascal Language Summary" provides a summary of the
Pascal language syntax.
Appendix C - "Relationships to ISO Pascal" covers the differences
between SVS Pascal and ISO standard Pascal.
Appendix D - "Relationships to UCSD Pascal" covers the differences
between SVS Pascal and U CSD Pascal.
Preface
Chapter 1 - Introduction
record type may actually contain different structures. That is, the number and
types of the components may differ between different instances of the same
type. The particular variant which the specific variable assumes is indicated by
a field called the tag field, common to all variants of that record.
A set is a homogeneous collection of elements selected from some base
type. The base type might be a user defined scalar type or a subrange of some
scalar type such as integer or char. A Pascal set is the collection of values
comprising the powerset of the base type. That means, the set of all subsets of
that base type.
A string data type is a sequence of characters whose length can vary
dynamically during program execution. A string has a maximum length (its
static length) which is determined when it is defined. There are a rich set of
intrinsic procedures and functions to manipulate strings.
A file is a sequence of components of the same type. The sequence is
normally associated with external storage or input and output devices, so that
files are the means whereby a Pascal program communicates with the world
outside of the computer. Files can be sequential such that there is a natural
ordering, and only one component of the file is accessible at anyone time, or
they can be random, such that any given component of the file is accessible on
demand.
Explicitly declared variables are called static, in that they are known at
compile time (lexically static). A declaration associates an identifier with the
variable. The identifier is subsequently used to refer to that variable. In
contrast to static variables, dynamic variables are created by executable
statements. Such a dynamic creation of a variable yields a pointer (which
substitutes for an explicit declaration), that is subsequently used to refer to the
dynamically allocated variable. Any given pointer variable may only assume
values pointing to variables of a specific type, and is said to be bound to that
type. A pointer may be assigned to other pointer variables of the same type.
Any pointer can assume the value nil - a universal pointer that is not bound
to a specific type.
The assignment statement is the fundamental Pascal statement. It assigns
a newly computed value to a variable or a component of a variable. New
values are obtained by evaluating expressions. Expressions consist of variables,
constants, sets, operators, and functions, operating on specified objects, to
produce new values. Operands of expressions are either declared in the
program, or are standard Pascal entities. Pascal defines a fixed set of operators
that can be considered to define a mapping from given operand types into
result types. Operators encompass the four groups: (1) arithmetic operators,
(2) Boolean operators, (3) set operators, and (4) relational operators.
A procedure statement causes execution of a designated procedure. This is
known as activating or calling the procedure. Assignment and procedure
statements are the basic. elements of structured statements. Structured
1.2 Metalanguage
A "metalanguage" is a collection of notations that describe another
language. In this case the language being described is Pascal. The
metalanguage used in this manual to describe Pascal is a modified version of
the ubiquitous Backus-Naur Form, or BNF (first used to describe Algol). A
description of the metalanguage follows.
Syntactic constructs which are enclosed between "angle brackets" < and
> define the basic language elements. Every language construct should
eventually be defined in terms of basic lexical constructs defined in the
remainder of this chapter.
A construct appearing outside the angle brackets stands for itself, that is,
it is supposed to be self denoting. Such a construct is known as a terminal
symbol. Terminal symbols and reserved words appear in bold face text
throughout this manual.
The sym bol :: = is to be read "defined as".
The symbol .. means "through", indicating an ordered sequence of things
where only the start and end elements are specified. (The reader is left
to infer the middle elements). For example, the notation 'a' .. 'z' means
"the ordered collection starting with the letter 'a', ending with the letter
'z', and containing the letters 'b', 'c' .... 'x', 'y' in between". In other
words, all the lower case letters.
The "vertical bar" symbol I is read as "or". It separates sequences of
elements that represent a choice of one out of many.
The metalanguage construct {... } (elements inside braces) enclose
elements which are to be repeated "zero to many times". Although the
braces are also used as one of the forms of comment delimiters in Pascal,
this should not cause any ambiguity. The one case where ambiguity
would occur is in the definition of comments, and this is explicitly
pointed out at that time.
It is recognized that the syntactic descriptions are not completely rigorous
in that they do not cover semantic issues. For example, the syntactic definition
of a decimal number does not mention how big a number can be. Where the
formal descriptions fall short they are augmented with narrative English prose.
1.3.1 Alphabet
SVS Pascal uses an extended form of the ASCII character set for all text
related processing. ASCII is the American Standard Code for Information
In terchange. There are 128 characters in the ASCII character set: 52 letters
(upper case 'A' through 'Z', and lower case 'a' through 'z'), 10 digits, space
(often called "blank"), 33 "control codes" (such as "carriage return" and "line
feed"), and 32 graphic characters such as colon, equals sign, and so on. Pascal
also allows an additional 128 values to be used as data values, for a total of 256
possible data values.
The Pascal compiler recognizes the following alphabet or character set.
< letter> 'A' .. 'Z', 'a' .. 'z', and '_'
<digit> '0' .. '9'
<hex digit> <digit> I 'a' .. 'f' I 'A' .. 'F'
< ASCII graphic characters> !"#$%&'{)*=
+-,./<>? [
@~I-'{}~:]
Note that the definition of < letter> above includes the underline
character.
Examples of Identifiers
_X25
UPanddown upandDOWN upANDdown
The last three identifiers in the examples are equivalent because the compiler
folds letters to a single case.
1.3.3 Numbers
Numbers are used to denote integer, real, and double data elements.
Integers are assum~d to be in the decimal number base, unless designated as a
hexadecimal number.
1. J. 4 Pascal Strings
Sequences of characters enclosed in apostrophes are called strings.
Strings of one character are constants of type char. A string of "n" characters,
where "n" is greater than one, is an ambiguous constant that is either a string
value, or is a value of the type packed array [1 .. n] of char. The exact type of
such a string constant is determined from the context in which it appears.
A string constant which is just simply two juxtaposed apostrophes "
represents a variable string constant of length zero.
SVS Pascal provides for entering any character value into a string by
coding its two-digit hexadecimal value preceded by a reverse slash \. This
means that non-printing characters such as "BEL" and "ETX" may be entered
into a string. A \ sign followed by a non-hexadecimal digit is simply that
character. Thus '\ Y' is equivalent to 'Y', '\\' represents '\' and '\3X'
represents '\03X'. This last case is interesting in that leading zeros are implicit
in the hexadecimal number if there is only one hexadecimal digit followed by a
non-hexadecimal digit.
An apostrophe in a string is represented by two juxtaposed apostrophes.
The rules for reverse slash character representations above means that an
apostrophe can also be represented by the string '\', or by the string '\27'.
<string> :: = '< character> {< character> },
< character value> :: = < two digit hexadecimal number>
Examples of Strings
+ Adding Operator.
Subtracting Operator.
* Multiplying Operator.
/ Division Operator (for real and double data types).
Assignment Operator.
Terminates a Pascal Compilation Unit;
Separates integer from fraction in a real or double number;
Indicates reference to a field of a record.
Separates items in lists.
Statement and Declaration Separator.
after case and statement labels; variable and parameter descriptions.
string delimiter.
Relational equality operator; Used in constant and type definition.
<> Relational operator for inequality.
< Relational operator for "less than".
<= Relational operator for "less than or equal to".
>= Relational operator for "greater than or equal to".
> Relational operator for "greater than".
( and) encloses lists of elements; encloses parts of
expressions that are to be considered indivisible factors.
(and) encloses array subscripts and lists of set elements.
{and} comment delimiters.
(* and *) are an alternative form of comment delimiters.
pointer dereference operator.
indicates a range of elements.
1.3.8 Comments
Comments in Pascal may appear anywhere that a space may appear, and
in fact, serve the same purpose as do spaces. But note that a comment within
a string constant is part of the string constant and is not really a comment.
Pascal comments are enclosed between braces {... } or between the characters (*
and *).
Page 10 Pascal Reference Manual
Chapter 1 Introduction
One of Pascal's major attractions is the ease with which users can
describe and manipulate data. An important aspect of structured programming
technology is the ability to structure data as well as control statements. This is
provided in Pascal through the notion of a data type.
A type defines a collection of values that a variable, constant or
expression may take on. A type has an associated size, but of itself reserves
no storage space. Storage is only reserved when a variable is declared as an
instance of that type. Although Pascal data types can be quite complex, they
are ultimately composed of simple unstructured components. An example is
the predefined type integer. Its size is two bytes (16 bits). The set of values it
contains is -32768, ... , -1, 0, 1. .. ,32767.
In addition to having a size and a set of values, a type has a collection of
operations in which values of that type can participate.
Pascal provides a number of predefined types (some of which were
described in Chapter 1), as well as the means for users to define their own
types. Section 2.2 of this chapter describes all predefined Pascal types.
Type constructors are the means by which users can define their own
types. Structured type constructors facilitate the definition of new and larger
types based upon other existing types as components.
storage.
longint is a long integer type. It is equivalent to a subrange defined
by a type definition that looks like:
longint = -2147483648 .. 2147483647
The longintdata type therefore occupies 32 bits of data
storage.
real real type is a subset of the continuum of real numbers. Reals
are represented in the "floating point" format which consists
of a fractional part (a mantissa) and an exponent. The range
of real numbers is approximately -3.4E38 .. +3.4E38, with
a precision of approximately seven decimal places. In
addition, the real data type can take on "extreme values",
such as plus infinity, minus infinity, and "Not a Number"
(abbreviated NaN), which arise from overflow and division
by zero. There is a detailed discussion of extreme values in
Appendix E - "Data Representations".
double double type is a double precision form of the real data type
described above, and is a subset of the continuum of real
numbers. Double numbers are represented in the "floating
point" format which consists of a fractional part (a mantissa)
and an exponent. The range of double numbers is
approximately -1.8D308 .. + 1.8D308, with a precision of
approximately 15 decimal places. In addition, the double data
type can take on "extreme values", such as plus infinity,
minus infinity, and "Not a Number" (abbreviated NaN),
which arise from overflow and division by zero. There is a
detailed discussion of extreme values in Appendix E - "Data
Representations" .
Boolean Boolean type represents the ordered set of "truth values"
whose constant denotations are false and true. Boolean is
conceptually equivalent to an ordinal type specified by a type
definition that looks like:
Boolean = (false, true)
char character type defines the set of 256 values of the ASCII
character set, and is equivalent to the subrange defined by a
type definition that looks like:
char = '\0' .. '\255'
An unpacked char data item occupies one word or 16 bits of
data storage. A packed char data item occupies one byte or 8
bits of data storage.
small_integer o .. 15;
daysJn_year 1 .. 366;
positive~ in teger o .. 32767;
lower_case_letters 'a' .. 'z';
colors (red, orange, yellow, green, blue);
hot_colors red .. yellow;
cold_colors green .. blue;
hues red .. blue;
days (Saturday, Sunday, Monday, T, W, T, Friday);
weekdays Monday .. Friday;
weekends Saturday .. Sunday;
the collection.
Pascal makes available five structuring methods: array, string, set, record
and file. Each type is described in the subsections to follow.
A structured type may be given the packed storage attribute. This
"advises" the compiler that the structure is to use data storage economically, by
packing the components of the structure densely. Packing is often achieved at
a cost of larger code size and slower execution speed.· Furthermore, a
component of a packed variable can not be passed as a var parameter to a
procedure or function (this restriction applies to components of packed array
of char). A full discussion on how components are packed can be found in
Appendix E - "Data Representations".
The alternative forms of specifying array types are equivalent. The first
form can be thought of as a shorthand notation for the second form. There is
a similar choice of notations when specifying the index elements for accessing
an array component.
When the index type is a subrange of the type integer, the type:
packed array [1 •• nJ of char
is a special case. Objects of this type up to a maximum length of 255
characters can be compared as single entities, whereas arrays of other data
types must be compared element by element. A literal string constant can be
assigned to a packed array of char, providing that the lengths are the same.
The type of a literal string of length 'n', where 'n' is greater than 1 is
compatible with the type:
packed array [1 .• nJ of char
rows = 1 .. 3;
columns = 1 ., 4;
bottle_quantities = array [bottle_sizes] of integer;
standard_case = packed array [rows]
of array [columns]
of bottles;
token = packed array [I .. 100] of char;
Note that the < tag field> is optional in a variant record definition.
2. 5. 4 Set Types
A set type definition serves to define the base type that the set is to use
in future manipulations. Sets are limited to 2032 elements. The range of the
set elements must be within the range 0 .. 2031.
2. 5. 5 File Types
A file type. defines a sequence of elements. A file is usually associated
with external storage devices or communication devices. SVS Pascal supports
the standard Pascal typed files, untyped files and an interactive file type more
suitable for terminals.
When a file variable "f' with components of type "T" is declared, there is
an additional implied declaration of a so called bujjer variable or "window", also
of type "T". This window is referenced by the notation r where "f' is the file
variable. This window is used in conjunction with the GET and PUT
procedures (see Chapter 6 - "Input and Output") and serves to append
components to the file when writing, and to access the components when
reading from the file.
<file type> ::= file of < type>
I file
SVS Pascal supports untyped files. An untyped file can be considered to
not have a window variable. Such files must be accessed using the
BLOCKREAD and BLOCKWRITE functions described in Chapter 6 - "Input
and Output".
A file of the pre-defined type text can be considered to be defined by a
type definition of the form:
text = packed file of char;
Such a file is special in that the range of its components (characters) are
extended to include an end-of-line marker. Such a file can then be
conveniently structured into lines. The EOLN predicate described in Chapter 8
- "Standard Procedures and Functions", covers how the end-of-line is
detected.
SVS Pascal also supports an interactive file type which display different
behavior in the way that tl).e READ, READLN and RESET intrinsics work.
block_access file;
numbers file of integer;
Capping_Line file of bottles;
Terminal interactive;
legible_file text;
blackboard = record
long_side : integer;
short_side : integer;
end;
cue = Ablackboard;
Two W ay = record
next: ATwoWay;
previous: ATwoWay;
stuff: array [0 .. 10] of integer;
end;
SymTree = record
name: string [3 1];
LeftNode: ASymTree;
RightNode: ASymTree;
end;
type_x integer;
type_y integer;
type_l set of char;
type_2 set of char;
id_type type_I;
In the above example, the types "type_x" and "type_y" are identical,
because they are defined to be the same type, integer. The types "type_I" and
"type_2" are not identical, since they occur in different type definitions. The
types "type_I" and "id_type" are identical however, because "id_type" is defined
to be the same as "type_I".
Chapter 3 - Variables
This chapter covers two topics. First there is a discussion of how Pascal
variables are declared in terms of the data types described in the previous
chapter. Then there is a description of the way that variables of different types
are accessed or referenced.
ChickenTeeth
GiddyGoatHorns
First
Chapter 4 - Expressions
The div operator applies to values of type integer only and represents
truncating division. div always truncates towards zero. It is an error to divide
by zero. If the signs of the operands are the same, the result is positive; if the
signs are different, the result is negative.
The mod operator defines the modulus operation between two values of
type integer. It is an error if the right operand of mod is zero. The
interpretation of mod is:
a mod b = a - (a div b) * b
When applied to operands of type Boolean, the and operator produces a
result of type Boolean as one might expect. When applied to operands of type
integer however, the and operator performs a bitwise logical and on the
operands and produces a result of type integer.
considered to form a hierarchy, with the integer data type at the bottom of the
pecking order, the double data type at the top, and the real data type in the
middle. If the operands are of different numeric types, the lower type of
operand is converted (or promoted) to the type of the other operand prior to
the comparison. For example, in the expression:
integer type < double type
the integer operand is converted to double before the comparison is made.
For operands of type Boolean the relation false < true defines the
ordering.
For operands of type char the relation "a" op "b" holds if and only if the
relation ORD(a) op ORD(b), holds, where op denotes any of the six
comparison operators and ord is the mapping function from type char to type
integer defined by the ASCII collating sequence.
For operands of any ordinal type "T", "a" = "b" if and only if, "a" and "b"
are the same value; "a < b" if and only if, "a" precedes "b" in the ordered list
of values that define "T".
real and double data types can generate several different extreme values.
The extreme value of positive or negative infinity is a result either of
overflow, or by dividing a non-zero value by 0.0.
Underflow generates a value of zero.
Dividing 0.0 by 0.0 generates a value of Not a Number (NaN).
Appendix E - "Data Representations" contains a description of the
extreme values and their behavior in comparisons.
const
version = lO;
if version 7 then
writeln('Too old!')
else
writeln('Not too old!');
The code fragment above, with the constant "version" set equal to 10, has the
same effect as a code fragment like this:
writeln{'Not too old!');
Chapter 5 - Statements
The actual parameter list must be compatible with the formal parameter
list of the procedure. An actual parameter corresponds to the formal
parameter which occupies the same ordinal position in the formal parameter
list.
Only formal parameters that are value parameters can have an actual
parameter which is an < expression>. Value parameters must be assignment
compatible with the type of the formal parameter.
Formal parameters that are var parameters must have actual parameters
that are identical types. In addition, the actual parameters must not be
components of packed objects.
Examples of If Statements
{ an else if chain
if weather = raining then
sleep_in
else if lawn = wet then
clip_the_hedge
else if grass > 6 then
mow_theJawn
else
turn_on_lawn_sprinklers
{ A dangling else clause
if condition_l then { 1 }
if condition 2 then {2}
if co;dition_3 then { 3 }
..... statements .....
else { goes with statement 1
..... statements .....
else {goes with statement 2
..... statements .....
else { goes with statement 3
..... statements .....
Case selectors and the statement tags must be non-real scalar types. In
addition, the case selectors and the statement tags must be of assignment
compatible types.
It must be stressed that the selection specifications which the component
statements are tagged with are not labels in the Pascal sense, and as such,
cannot be used as the target of a go to statement, and neither should they
appear in any label declaration part.
case wine_type of
Champagne:
Anything_goes;
Cabernet:
Roast_Lamb;
Chardonnay:
Veal_Piccata;
otherwise:
Hamburger;
end;
The < statement> is repeated while the value of < expression> remains
true. The <expression> must be of type Boolean. When < expression>
becomes false, control passes to the statement after the while statement. If
the value of < expression> is false at the time that the while statement is
encountered for the first time, the subordinate statement is never executed at
all. Thus the while statement provides a means to "do nothing gracefully".
Contrast this behavior with the repeat statement described below.
< repeat statement> :: = repeat < statement list> until < expression>
repeat
consume_glassfull;
refill glass;
until (Cha~pagne_Volume < = 0) or (Consumer = Blotto);
The control variable is set to the initial value. After every iteration the
control variable is either incremented (to) or decremented (downto) until its
value is greater than or less than the final value.
The control variable, the initial value, and the final value, must all be of
the same scalar type or a subrange of that scalar type. No part of the
statement controlled by the for statement may alter the control variable during
the execution of the for statement.
Neither the control variable, nor the initial value, nor the final value,
may be of type real. The control variable must be local to the procedure or
function that contains the for statement.
The value of the control variable is undefined on normal termination
from the for statement. If the for statement is exited prematurely (via a got(l
statement), the value of the control variable is defined.
Within the body of the with statement, fields of the specified record
variable do not need to be qualified by the name of the record.
If there is a local variable "x" and a field "x" in a record "r" which is the
subject of a with statement, the statement:
with r do
"hides" the local variable "x" until the end of the with statement.
A with statement which has multiple < record variable> fields is
interpreted as nested with statements. The statement:
with record_I, record_2, record_3 do
is equivalent to the statement:
with record_I do
with record_2 do
with record_3 do
..... statement .....
var
TreeTop: SymTree;
with TreeTop do
begin
LeftNode := nil;
RightNode := nil
end with }
This is a shorthand for the following statements
TreeTop.LeftNode : = nil;
TreeTop.RightNode := nil
Input and Output facilities provide the means whereby a Pascal program
can communicate with the world outside the computer system on which it
runs.
SVS Pascal supports the input-output facilities as defined by standard
Pascal, and additionally supports untyped (block access) files, interactive files,
random access to typed files and unit input-output (direct access to the devices
on the system).
type
whammo = file of gobion;
var
frammis: whammo;
Curcomp: gobion;
When the file "frammis" is opened for reading via the RESET procedure
call, the first component of the file is in the buffer variable. An assignment
statement of the form:
CurComp := frammis";
assigns the contents of the buffer variable to the variable "CurComp". The
contents of the buffer variable then become undefined. The next component
from the file is moved into the buffer variable by a GET procedure call.
When the file "frammis" is opened for writing via the REWRITE
procedure call, the buffer variable is undefined. An assignment of the form:
frammis" : = CurComp;
assigns the value of the variable "CurComp" to the buffer variable. A
subsequent PUT procedure call appends the contents of the buffer variable to
the file "frammis". The contents of the buffer variable become undefined until
another assignment defines it.
For files of type interactive the handling of the buffer variable is
different. In standard Pascal, when a file is RESET, the first element of the
file is read and placed in the file buffer variable. This means that the system
would expect the user to type a character at the terminal, else the system
would "hang". Thus a RESET on an interactive file does not perform an
immediate GET. This affects the way that EOLN functions. When an end-of-
line is read, EOLN becomes true and the character read is a space.
If the variable had previously been opened, access to the previous files is
lost, and no close or buffer flushing is done. For a 'proper' closing of any
opened file, a specific call to close must be done.
SVS Pascal requires a second parameter to REWRITE. This parameter is
the name of a disk file. The parameter can be a string variable or constant.
The third parameter to RESET is an option to determine whether the file
is buffered or unbuffered. The buffering option may be specified as the
keyword BUFFERED or UNBUFFERED, and it is described in the subsection
below.
vn := file"; GET(file);
GET(file);
where the "v n" are the list of variables to read into.
Note that the type .of each variable in the list must be identical to the
type of the elements in the file.
The < file> parameter in all cases is a file variable which refers to the file
on which to append character strings. If the < file> parameter is omitted,
output is written to file output (the computer standard output).
is of the form:
WRITE(number:f)
results in a number of the form:
+x.yyyyyE +nn
where "f' is the total number of characters in the converted number. There is
one digit before the decimal point and "f'-7 digits after the decimal point.
WRITE (number:f:w)
results in a number of the form:
xxx.yyy
where "f' is the total number of characters (including the decimal point), and
"w" is the number of digits after the decimal point.
The extreme real and double values are printed as follows: positive
infinity prints as a row of + signs; negative infinity prints as a row of - signs;
NaN (Not a Number) prints as a row of ? marks.
length as needed.
mean that the file could not be RESET, so the program then tries a REWRITE
statement. If that fails, then the program halts.
program complete;
var i: integer;
begin
i:= 17;
writeln (0;
end.
The above program is complete and can be compiled and executed. It does not
make use of any separate compilation.
program missingsomething;
var i: longint;
procedure getvalue(var fi: longinO; external;
procedure callme;
begin
writeln ('I got called! ');
end;
begin
getvalue (i);
writeln (i);
end.
This example illustrates the call on an external procedure called getvalue
which will have to be supplied in the linking process in order to make a
complete executable program. It is possible that this external procedure has
been written in assembly language, or in SVS FORTRAN, or in Pascal. (Note:
if the procedure had been written in SVS C, .the calling sequence to the
external would have to be different and the programmer should have coded
getvalue as a cexternal instead of an external).
Regardless of the origin of getvalue, the Pascal system will make no
attempt to match parameter types, etc. between the call and the code called.
Pascal is satisfied that the external declaration describes the interface and it is
the programmer's responsibility to insure that the receiving subroutine is
suitable. Thus, this method of independent compilation is referred to as
"insecure" .
The example also contains a procedure "callme" which may well be
referenced in some other compilation unit as an external. This other
compilation unit must not, however, contain a main program, since it is not
allowed to link together" .obj" files containing more than one main.
unit IHideAndHoldAndPrintX~
interface
var publicinteger: integer~
procedure setx (fx: real) ~
procedure printx~
implementation
var x: real~
procedure setx~
begin
x:= fx;
end~
procedure printx~
begin
writeln (x) ~
end~
end.
This example creates a unit with two procedures in its public part and a
private variable. The" .obj" created by the Pascal system for this unit contains
linkable object code for the two procedures and contains the source code for the
interface section of the unit. Let us assume that the ~reated object code for
this unit is named "hide.obj".
When another compilation "uses" this unit (see example below), which is
to say uses the ".obj" code of this unit, the interface source code declarations
are extracted from the unit's ".obj" file and processed to insure that interfaces
match properly. This is why the unit mechanism is referred to as "secure"
independent compilation.
checks and enforces that the interfaces are matching between this compilation
and the unit.
The Pascal system must be told what the file name of the" .obj" of the
referenced unit is. This is done using the $U directive. In the event that more
than one unit is to be used, the following method should be utilized:
uses {$U file1.obj} FirstUnit,
{$U file2.obj} SecondUnit;
The order in which these units are used may be important. If the SecondUnit
unit used FirstU nit when it was compiled, it more than likely depended on
FirstUnit to make its own declarations meaningful. In this event, the order
must be as shown.
The examples shown here illustrate only a few of the possibilities. Units
can use units. Global procedure and function names in programs and interface
procedures and functions in units become available for reference via the
external mechanism, etc.
The key to properly using units is to remember that the interface
information is included in the using compile as source declarations. This fact
determines the order in which compilation must be done and what must used
where and in what order.
The more formal details of compilation units follows.
A compilation unit is either a program (a main program), or a unit. A
complete executable program consists of a single program and zero or more
units.
A program is a main program, consisting of all the statements between a
program statement and an end. statement. The main program is described in
more detail later in this chapter, in the section entitled "Program Heading".
A unit is a collection of declarations and statements packaged so as to
make parts of the declarations in the unit public to other parts of the same
compilation unit or separate compilation units. Units are useful for sharing
common code among different programs or as a means to avoid compiling a
huge program every time one line is changed. Units are compiled separately.
A program or unit that uses another unit is known as a "host". A host
uses other units' declarations by naming those units in uses declarations. The
uses clause appears after a program heading or it appears in a unit at the start
of the interface section (see below).
A unit contains two major parts, namely an interface part which describes
how other units view this unit, and an implementation part which supplies the
unit GanipGanop;
interface { This part declares the
{ interface section
uses names of { This part is optional if
other units { GanipGanop does not use any
{ things from other units
{ Note that if any declarations
{ imported from other units are
{ referenced in the interface
{ part of GanipGanop then the
{ compilation that uses
{ GanipGanop must first uses
{ that other unit.
L.... declarations and
procedure headings
for the GanipGanop unit.
All these declarations and procedure
headings are PUBLIC to other units ;.... }
implementation This part declares the
implementation section
L....declarations and
code for the GanipGanop unit.
All these declarations and code are
PRIV ATE to GanipGanop ..... }
end. of the GanipGanop unit }
The program region (over which ~ll uses of an identifier are associated
with the same object) is called the scope of the identifier. Within a compilation
unit, such a region is either a unit body or a block body. In the case of a unit,
the scope is a declaration list. In the case of a block, the scope is a statement
list preceded by an optional declaration list.
< program> :: = < program heading> {< uses clause>} < block> •
<program heading> ::=
program < identifier> {( < program parameters»};
< program parameters> :: = < identifier> {, < identifier>}
The identifier following the word program is the program name. It has
no further meaning inside the program. The program parameters are optional.
No global identifiers in the program may have the same name as any of the
program parameters.
Then there are the two variables associated with obtaining arguments from the
operating system command line (see the next subject heading below):
argc is a count of the number of arguments supplied on the command
line.
argv is an array of pointers to the character strings containing the
command line arguments.
type
stringtype = string [anylength] ;
pstring = string type;
A
var
argc: integer;
argv: array [I .. argc] of pstring;
Each element of argv contains a separate field from the command line
that invoked this Pascal program. If "argc" is zero (Q), no attempt should be
made to reference "argv". The first element of "argv" is the first parameter
from the command line. The name of the command itself mayor may not be
available as the first command line argument depending on the operating
system under which the program is run. A void assigning to any element of
"argv".
7.4 Declarations
All the definition and declaration parts above are optional, with the
exception of the < statement part> .
The procedure heading specifies the identifier that names the procedure,
and any formal parameters for that procedure.
Procedure parameters are either value parameters, variable parameters, or
procedure or function parameters.
<procedure heading> ::=
procedure < identifier>; {< attribute>;}
procedure < identifier> « formal parameters»; {< attribute>;}
<function heading> ::=
function <identifier>: <result type>; {<attribute>;}
function < identifier> « formal parameters < );( <attribute>;}
<formal parameters> ::=
<formal parameter> {;<formal parameter>}
<formal parameter> ::=
< parameter group>
var < parameter group>
< procedure heading>
< function heading>
< parameter group>
< identifier> {, < identifier> }: < type identifier>
< attribute> external I forward I cexternal
< result type> < simple type>
function declaration consists only of the header, and that the body of that
procedure or function appears later in the program source text, possible after it
is referenced. A forward-declared procedure or function, then, is actually
declared in two distinct parts: its header or prototype is declared, with the
forward attribute, before any reference is ever made to it; at some later point
in the program source text, its body is declared. At this later point, the formal
parameter section must not appear.
LENGTH returns an integer value which is the dynamic length of the string
"source".
The length of the string" is zero (0).
Examples of LENGTH
alphabet : = 'abcdefghijklmnopqrstuvwxyz'~
WRITELN (LENGTH (alphabet) , '
alphabet(1), ' ,
alphabet[LENGTH(alphabet»), '
LENGTH("»~
Example of COPY
var
left: string [I 00];
middle: string[IOO];
right: string[100];
title: string [255];
title: = 'Left Side. Middle Part. Right Side.'~
left := COPY(title, 1, 10);
middle:= COPY(title, 12,12);
right := COPY(title, 25,11);
WRITELN (teft) ;
WRITELN (middle);
WRITELN (right);
This should generate the output:
Left Side.
Middle Part.
Right Side.
POS scans from left to right trying to find an instance of the string
"pattern" in the string "inwhat". If a match is found, POS returns an integer
value that is the position in "inwhat" at which the "pattern" starts to match.
If there is no match, the result is zero (0).
If "pattern" is longer than "inwhat", the result is zero (0), or no match.
If no "pattern" is the null string, ", the result is one (0, since the null
string matches the first position in any string.
Example of POS
SCANxx scans "object" for "len" characters, or until the character "what"
is found (SCANEQ) or not found (SCANNE). The result is the offset into
"object" where the scan stopped. If the character "what" is not found
(SCANEQ) or is found (SCANNE), SCANxx returns the value "len". If the
"len" parameter is positive, scanning is from left to right; if the "len"
parameter is negative, the scan proceeds from right to left, and a negative
value is returned.
Note that the SCAN xx functions simply look at bytes in memory. They
ignore any higher level structure that the user might perceive or might have
imposed on the object. Thus "object" is simply an address in memory at which
to begin scanning (or in the case where "len" is negative, to end the scan).
Thus, for example, if the programmer were to do a SCANEQ on a data type of
string[80], the length byte orthat string would also be scanned, and the results
might be unexpected.
var
large: string[IOO];
large := 'A long exhausting rally, eh what, chaps';
DELETE(Iarge, 8, 11);
WRITELN (large);
This should generate the output:
A long rally, eh what, chaps
const
UpperLimit = 255;
type
LArray = array[l .. UpperLimitl of integer;
ArrayAddr = ALArray;
var
head: Array Addr;
NEW(head);
if head = nil then
..... take some recovery action .....
else
begin
headA[I) := 0; {zero fill array }
A
MOVELEFT(headA[I), head [2),
SIZEOFOnteger)*(UpperLimit - 1);
and so on .....
end
Example of MOVELEFT
Example of FILLCHAR
HALT(i: integer);
The "i" parameter is optional. If the "i" parameter is omitted, by simply
executing a
HALT
statement, the correct "no error" code is returned to the host operating system.
The HALT procedure also returns a value to the CALL function,
described below.
A list of the values which the HALT procedure can return can be found
in Appendix A - "Messages from the Pascal System".
The value returned from the CALL function is either the value which a
program returns via a HALT call, or is on~ of the operating system error
codes.
NOTE: The CALL function is not available under all operating systems. See
Appendix G for specifics about this operating system.
$N+ or $N- Check the result of floating point expressions for validity. If
this option is enabled, then the VALUE of most floating
point expressions are checked for the values Not A Number
and INFINITY. If present, a run time error is caused. The
default is off.
$1 filename Include the file specified by "filename" at this point in the
source.
$1 + or $1 - Turn automatic Input Output checks on (+) or off (-). The
default is 1+.
$L filename Make a compilation Listing on the file specified by "filename".
If a listing file already exists, that file is closed and saved
before the new file is opened.
$L + or $L - Turn Listing on (+) or off (-) without changing the listing
file name. The listing filename must be -specified before
turning listing on. The default is $L+ (listing on) when a
listing file has been specified on the compiler's command line
or $L - (listing off) when a listing file was not specified.
When the list option is on, the listing is directed to whatever
list file was specified on the Pascal compiler's command line.
$M + or $M - The $M + option specifies that the Pascal run-time system
should check the stack and heap for overflow upon entry to
each procedure. The $M + option enables the check. The
$M - option disables the check. The default setting is $M-
(disable the check).
$F+ or$F- Generates code to use floating point hardware (+) or
software (-). In those implementations without floating
point hardware, this option is ignored. The default is off (i.e.
use software).
$P+ or $P- Specifies whether the Pascal compiler should prompt the user
for corrective action when errors are detected. The $P+
option indicates that the compiler should prompt the user as
to whether to continue the compilation when errors are
detected. The $P- option disables the prompting feature.
This feature is also available via the - p or + p option on the
compiler command line. The default setting of the $P option
is operating system dependent.
$Q + or $Q - Controls the amount of messages that the Pascal compiler
prints while compiling a program. The $Q + option results in
fewer messages. The $Q- option results in more messages.
The default setting of the $Q option depends upon the
operating system on which the Pascal system is running.
This appendix describes the error messages that the Pascal system
generates.
36 '~' expected
37 ' =' expected
38 ',' expected
39 '*' expected
40 ':=' expected
41 program keyword expected
42 of keyword expected
43 begin keyword expected
44 end keyword expected
45 then keyword expected
46 until keyword expected
47 do keyword expected
48 to or downto keyword expected
50 if keyword expected
51 '.' expected
52 implementation keyword expected
53 interface keyword expected
.... "what is the use of repeating all that stuff", said the Mock Turtle, "if
you don't explain it as you go along. It's by far the most confusing thing
I ever heard!" ....
Constants
maxint TRUE FALSE
Types
Boolean interactive longint text
char integer real double
Variables
Argc Argv Input Output
Stderr
Procedures
CLOSE HALT PUT UNITCLEAR
DELETE INSERT READ UNITREAD
DISPOSE MARK READLN UNITSTATUS
EXIT MOVELEFT RELEASE UNITWRITE
FILLCHAR MOVERIGHT RESET WRITE
GET NEW REWRITE WRITELN
GOTOXY PAGE SEEK
Functions
ABS EOLN MEMAVAIL SCANEQ
ARCTAN EXP ODD . SCANNE
BLOCKREAD FILLCHAR ORD SIN
BLOCKWRITE IORESULT ORD4 SIZEOF
CHR ISINF POINTER SQR
CONCAT ISNAN POS SQRT
COPY ISNUM PRED SUCC
COS LENGTH PWROFTEN TRUNe
EOF LN ROUND UNITBUSY
<expression> ::=
< simple expr>
1 < simple expr> < relational operator> < simple expr>
< multiplying operator> .. - * 1 / 1div I mod I and
< adding operator> .. - + I - 1or
< sign operator> .. - +1-':
< relational operator> .. - = I < > 1> I < 1> = 1< = 1in
<assignment statement> ::=
< variable> : = < expression>
< function identifier> : = < expression>
< procedure call statement> :: =
< procedure identifier> < actual parameter list>
< procedure identifier>
< actual parameter list> ..
« actual parameter> (, < actual parameter> })
<actual parameter> ::= <expression>
1 < procedure identifier>
1 < function identifier>
< structured statement> < begin statement>
< if statement>
< while statement>
< repeat. statement>
< for statement>
< case statement>
< begin statement> begin < statement list> end
< statement list> < statement> {; < statement>}
< if statement> :: =
if < Boolean expression> then < statement>
if <Boolean expression> then <statement> else <statement>
< case statement> :: = case < expression> of < cases>
{otherwise: < statement>} end
<cases> <a case> {; <a case>}
<a case> ..
< selection spec> {, <selection spec>} : < statement>
< selection spec> :: = < simple constant scalar expression>
<while statement> ::= while <expression> do <statement>
<repeat statement> ::= repeat <statement> until <expression>
The and, or, and not operators can be applied to operands of type integer
as well as operands of type Boolean. When applied to operands of type
integer, these operators perform bitwise logical and, logical or, and logical not
operations on their operands.
SVS Pascal supports many extensions. These mainly derive from the
UCSD P-System.
program, use the $S compiler option, which directs the compiler to place
generated object code in a named segment. See Chapter 9 which contains a
section on compiler options.
SVS Pascal does not implement unit initialization code.
SVS Pascal does not supply special units such as APPLESTUFF or
TURTLEGRAPHICS.
SVS Pascal does not have any default string length. Instead of the
declaration
var x: string;
use the declaration
var x: stringI80);
SVS Pascal does not have a predefined file called "keyboard".
SVS Pascal implements sets with elements 0 through 2031, whereas
UCSD Pascal implements 0 through 511.
Packing algorithms for arrays and records are different.
Internal storage for sets is different.
SVS Pascal does not support comparison of arrays and records, with the
single exception that packed array [l .. n] of char can be compared.
Predefined string procedures and functions must have string variable or
string literal parameters. That is, not packed array of char or char variable
parameters.
SVS Pascal does not implement the procedure STR, since there is no
integer[nnl type.
The file procedures RESET and REWRITE require two parameters,
namely (file,string).
End-of-file character from the keyboard is Control-D instead of Control-
C.
SVS Pascal text files must be declared as packed file of char.
SVS Pascal text file reads allow additional parameters of packed array of
char.
SVS Pascal text file writes allow additional parameters of packed array of
char and Boolean. .
Under most operating systems, SVS Pascal does not implement the unit
I/O routines such as UNITREAD, UNITWRITE, and UNITWAIT.
SVS Pascal does not implement TREESEARCH.
SVS Pascal has added the function ORD4. It is the same as ORD except
that it returns a 32-bit integer.
All integer arithmetic operations are done at a precision of either 16 or
32 bits, depending on the maximum size of any arguments. The rules are
similar to FORTRAN's singl~ and double precision reals.
SVS Pascal statement labels are restricted to the range 0 through 9999, as
in the ISO Pascal standard.
SVS Pascal provides for hexadecimal integer constants. A hexadecimal
-constant is prefixed with a S sign. Hexadecimal numbers must be 32 bits long
to be considered signed numbers, that is, SFFFF represents 65536, not -1.
To represent -1, code the hexadecimal constant SFFFFFFFF.
The and, or, and not operators can be applied to operands of type integer
as well as operands of type Boolean. When applied to operands of type
integer, these operators perform bitwise logical and, logical or, and logical not
operations on their operands.
This appendix describes the ways that SVS Pascal represents data in
storage, how that data is packed for data objects that have the packed storage
attribute, and the mechanisms for passing parameters to procedures and
functions. This appendix is intended as a guide to those programmers. who
wish to write modules in languages other than Pascal and have those modules
interface to PascaL
Whatever the size of the data element in question, the most significant
bit of the data element is always in the lowest numbered byte of however many
bytes are required to represent that object. The diagrams below should clarify
this.
bit --> 7 0
8-bit integer byte 0
15 0
integer byte 0 byte 1
3 0
longint byte 0 byte 1 byte 2 byte 3
31 30 23 22 o
I S Exponent Mantissa
63 62 52 51 0
I S Exponent Mantissa
I I I
I I Mantissa (52 + 1 bits)
I Exponent, biased by 1023
Sign
Normalized real and double numbers are said to coritain a "hidden" bit,
providing for one more bit of precision than would normally be the case.
Abbreviation Meaning
Den Denormalized Number
Num Normalized N urn ber
Inf Infinity (positive or negative)
NaN Not a Number
Uno Unordered
Multiplication
Left Right Operand
Operand 0 Den Num Inf NaN
0 0 0 0 NaN NaN
Den 0 0 Num Inf NaN
Num 0 Num Num Inf NaN
Inf NaN Inf Inf Inf NaN
NaN NaN NaN NaN NaN NaN
Division
Left Right Operand
Operand 0 Den Num Inf NaN
0 NaN 0 0 0 NaN
Den Inf Num Num 0 NaN
Num Inf Num Num 0 NaN
Inf Inf Inf Inf Nan NaN
NaN NaN NaN NaN NaN NaN
Comparison
Left Right Operand
Operand 0 Den Num Inf NaN
0 = < < < Uno
Den > < < Uno
Num > > < Uno
Inf > > > Uno
NaN Uno Uno Uno Uno Uno
Notes:
NaN compared with NaN is Unordered, and also results in inequality.
+0 compares equal to -0.
Max
Left Right Operand
Operand 0 Den Num Inf NaN
0 0 Den Num Inf NaN
Den Den Den Num Inf NaN
Num Num Num Num Inf NaN
Inf Inf Inf Inf Inf NaN
NaN NaN NaN NaN NaN NaN
Min
Left Right Operand
Operand 0 Den Num Inf NaN
0 0 0 0 0 NaN
Den 0 Den Den Den NaN
Num 0 Den Num Num NaN
Inf 0 Den Num Inf NaN
NaN NaN NaN NaN NaN NaN
var
blarg: daysJn_year~
bit --> 15 13 12 5 4 3 2 o
a b c d Ie
packed record
a: 0 .. 4095~
b: char~
end~
bit --> 15 11 0
extended ... a
15 0
b
packed record
a: 0 .. 63;
b: 0 .. 63;
end;
bit --> 15 10 9 4 3 0
a b hole
bit --> 15 14 13 8 7 6 5 0
a b
packed record
a: -1024 .. + 1023;
b: 0 .. 7;
end;
In the last example above, the signed subrange field was moved up to the
left hand end of the word and sign extended for faster access.
Packed arrays are also code consuming, with one exception: packed
array of char is treated as a special case, and the generated code is compact.
Elements of packed arrays are stored with multiple values in a byte
whenever more than one value can fit in a byte. Elements are allocated on 1,
2, 4 or 8-bit boundaries. This only happens when the value requires 4 bits or
less. 3-bit values are stored in 4 bits.
The first value in a packed array is stored in the lowest numbered bit
position of the lowest addressed (that is, the most significant) byte.
Subsequent values are stored in the next available higher numbered bit
positions in that byte. When the first byte is full, the same positions are used
byte 1 bit 0
I a8 a7 a6 as a4 a3 a2 al
byte 2
I .... Unused .... a12 all al0 a9
var
b: packed array[3 .. 8] of 0 .. 3;
byte 1 bit 0
I b[6] I b[S] b[4] b[3]
byte 2
I ..... Unused .... b[8] b[7]
var
c: packed array[O .. 2] of 0 .. 7;
or
c: packed array[O .. 2] of 0 .. 15;
byte 1 bit 0
I cU] c[0]
var
c: packed array[O .. 2] of 0 .. 7;
or
c: packed array[O .. 2] of 0 .. 15;
byte 2
I..... Unused .... c[2]
If the callee is not a procedure or function at the global level, the static
link is the last thing pushed onto the stack before the routine is called.
Upon return from a routine, all parameters are discarded from the stack.
Nothing should be on the stack upon return.
var parameters (call by reference) always have a four-byte pointer to the
variable pushed onto the stack.
Value parameters are divided into the three categories of sets, doubles,
and everything else.
The caller always pushes sets onto the stack. A set which occupies one
byte is pushed with a move.b instruction. A set which occupies more storage
than one byte is pushed with the least significant element in the most
significant word. Thus the representation of a set on the stack is the same as
the representation in memory.
The caller always pushes doubles onto the stack as well. This is usually
accomplished by two move.l instructions in such a manner that the
representation a double on the stack is the same as the representation in
memory (that is, with the sign bit in the lowest addressed byte).
F. 1.3 Linker
A utility is provided with SVS Pascal for linking .obj" files with each
II
other and with run time libraries which are part of the language system. The
linker is highly specific to the operating environment and its operation is
described in detail in the following appendix. There is, however, certain
general information which applies to all of the linkers.
Each linker accepts as inputs ".obj" files and produces an output which is
acceptable to the operating system as an object file. In some operating
environments, the linker's output file is further linkable in the target
environment with object code generated by the operating system assembler,
etc. In all cases, the linker may be run only once per executable image. The
input to the linker must contain exactly one main program but may contain
many object files derived from units.
F.1. 4 Libraries
Object files in .obj" format mayor may not be libraries. The result of a
II
possible that such a file contains object code with corresponds to many
subroutines. The main difference between .obj" files which are libraries and
II
those which are not libraries is that the linker includes all of the object code
from non-library input files but only that object code which is referenced from
library input files. The determination of what is referenced is made based on
unresolved external code references in previous input files to the linker.
Therefore the order that files are presented to the linker is important.
When linking Pascal programs, the run time library provided with the
system, paslib.obj, must be the last input file to the linker.
Under systems in which the code generator is not directly invoked by the
Pascal compiler front end, the code generator is invoked using a command of
the form:
code pTOg.i {optionalfname}.
where leaving off the optional file name results in an output file named
prog.obj. If the optional file name is provided, the output file is named
optionalfname.
See the appendix which follows for a description of command line
arguments and options related to the linker.
.text
.globl pasfunc
.globl PASFUNC
pasfunc:
movl sp@ + ,savera
jsr PASFUNC
subl #16,sp
movl savera,-sp@
rts
.bss
savera: . = . + 4
to call a Pascal function declared with the header
function pasfunct(ij: longint; d: double): longint;
The important items to note are: Pascal entry point is in upper case, C
external reference is in the same case as the programmer specified. The .globl
for the C entry point may need a prepended underscore on some operating
systems. The "wrapper" will not work if the interlanguage call is recursive. The
C calling site expects to pop off 16 bytes of parameters after the call returns,
but the Pascal function has already popped off the parameters. Therefore, the
"wrapper" decrements the stack pointer by the amount the calling site expects
to pop off.
The exact syntax of the assembly language will vary from system to
system. In general the object code for "wrapper"s is linked into the executable
program at the last linking step of the compile. Normally, a wrapper is
required for each C to Pascal call.
The above procedure will not work with C systems other than S VS C because
other C systems expect called subroutines to preserve different registers than
Pascal functions preserve. In this case, the "wrapper" must be enhanced to
preserve the registers required by the calling C language subroutine.
on your system.
The lines of the shellscript do the following: The set - e causes the
compiling sequence to terminate after an error is detected. The next lines run
the front end and code generator on files whose names are derived from the
command line in which the shellscript is invoked. The linker is run (in its
simplest form, see below for more details) with -I inhibiting a linkmap listing
file, with output file $1.0, and with two input files, including the SVS supplied
library. Ulinker produces a file which is then linked to those UNIX system
calls which are utilized by the program in the cc step (which invokes the UNIX
system linker>. The final two lines rename the executable program and
remove the unlinked object code files.
G.3 Ulinker
Under UNIX, ulinker is the SVS linker. The general operation of the
linker is described in Appendix F. This section will describe in detail the
modes of operation of ulinker and its load map listing option.
G. 3. 2 Ulinker OUlputs
Ulinker creates partially linked object code in UNIX ".0" format as its
primary output. Optionally, ulinker can produce a listing file which is a load
map of global entry points in the created .0" file. The form of this map and
II
The listing file was generated from the following Pascal program:
program fairlysimple~
var i: integer~ Ii: longint~
procedure computesome~
begin
Ii : == (H * Ii) mod 99999~
Ii :== Ii div 17~
end~
begin
Ii :== 2~
for i :== 1 to 100 do
computesome~
end.
The segment named by 8 blanks had 670 (decimal) bytes in it. Under UNIX
there is no reason for programmers to explicitly deal with segments, since
ulinker handles this automatically.
There were ten entry points in the linked files. Eight of these were
pulled out of the library and two are recognizable as user function names. The
addresses of these entry points are given in hex and are text area relative, but
will be further relocated by the cc step of the compilation. The relative addresses
(distance between them) will remain intact through the cc step.
There would be a data areas shown associated with each of the units in
the link, mapped to the data or bss area depending upon whether the area is
initialized at compile time (which is possible using FORTRAN block data and
named common). Sizes and locations of these data area listings are in hex and
relative to the start of the data or bss area as appropriate.
G.3. 7 Segments
Under some operating systems other than UNIX, the SVS Pascal system
contains a meaningful object code concept referred to as segments. Under
UNIX, there are segments in the object code, but they are not semantically
meaningful. Ulinker automatically creates segments as needed and there is no
reason for the user to do anything explicitly. about creating and/or naming
segments.