Multics Technical Bulletin MTB 632
To: MTB Distribution
From: Melanie Weaver and Jean-Michel Athane
Date: 09/16/83
Subject: Pascal Symbol Tables
ABSTRACT
This MTB describes the new standard data types for Pascal and the
Pascal symbol node format. These are necessary in order to
implement full probe support for Pascal.
Although the overall symbol tree structure is the same as that
currently in use, the Pascal node format is quite different. It
is anticipated that other new languages will also have different
symbol node formats. Until now, probe and stu_ have referenced
symbol nodes directly. However, they are already very
complicated and continuing this practice could make them
unmanageable. Thus the knowledge of the node format has been
removed from them and put into a new intermediary procedure.
Comments may be sent
by Multics mail to
Weaver.Multics
or by U.S. mail to
Melanie Weaver
Honeywell Information Systems, Inc.
575 Technology Sq.
Cambridge, MA 02139
(617) 492-9312
HVN 261-9312
______________________________________________________________
Multics Project internal working documentation. Not to be
reproduced or distributed outside the Multics Project.
MTB 632 Multics Technical Bulletin
NEW DATA TYPES FOR PASCAL
Introducing Extended Data Types
Seventeen new data types are required for Pascal. Even some that
seem similar to PL/I types are represented differently enough
that they need their own type codes. Unfortunately the type
fields in descriptors and symbol nodes are only 6 bits and there
are no longer 17 unused types codes in that range. Thus it is
time to go to extended data types, which will be fixed bin (17)
numbers. Extending the type field by one bit would be adequate
but would be almost as incompatible. The changes necessary for
any extension remove the need to conserve bits. The new
conventions for descriptors and symbol nodes are described below.
Elsewhere, types are already fixed bin (17) numbers.
DESCRIPTOR CHANGES
Descriptors for the new types have 58 (decimal) in the type
field. This indicates that the second word of the descriptor
contains the real type in the first half and an optional symbol
node offset in the second half.
The symbol node offset is relative to the beginning of the symbol
tree (i.e. pl1_symbol_block). It is intended to be used
eventually for runtime parameter checking. In cases where the
descriptor type is enumerated type instance or user defined type
instance, the symbol node offset points to the node describing
the type itself.
Descriptors for arrays contain the array dimension information
(three words for each dimension) immediately following the first
word, followed by the type / symbol offset information. This
enables Pascal programs to call programs in other languages with
conformant arrays.
NEW SYMBOL NODE VERSION
New symbol node structures have been defined with the type field
as fixed bin (17). There is currently not a version number in
the symbol node structure, which makes defining a new format more
difficult. Instead, the first bit indicates whether the node is
in PL/I version 1 or PL/I version 2 format. Since version 1 PL/I
support can now be eliminated, the first bit in the symbol node
can be used to indicate a new style. According to the new
definition, if the first bit is "0"b, the second half of the
first word in the symbol node contains a version number. At
first, only Pascal will produce these. There are no plans to
change PL/I in the near future.
Multics Technical Bulletin MTB 632
Pascal Data Types
NEW TYPE VALUES
The new Pascal data types are listed below. Some will only
appear in symbol table nodes. The representations are described
in Appendix A.
64 Pascal typed pointer type
65 Pascal char
66 Pascal boolean
67 Pascal record file type
68 Pascal record type
69 Pascal set type
70 Pascal enumerated type
71 Pascal enumerated type element
72 Pascal enumerated type instance
73 Pascal user-defined type
74 Pascal user-defined type instance
75 Pascal text file
76 Pascal procedure type
77 Pascal variable formal parameter
78 Pascal value formal parameter
79 Pascal procedure formal parameter
80 Pascal procedure parameter
OTHER TYPES USED BY PASCAL
The other data types used by Pascal are listed below.
1 integer
4 real
24 label
MTB 632 Multics Technical Bulletin
25 internal procedure
26 exportable procedure
27 imported procedure
Passing Arguments To Procedures In Other Languages
Adding new data types may eventually make it more difficult to
pass arguments between programs in Pascal and other languages,
since the the descriptors won't match. (Currently Pascal
arguemtn lists do not contain descriptors.) Many data types, of
course, are not translatable. However several types, including
some user-defined types, are compatible.
This is part of the more general problem of passing arguments
during inter-language calls. So far, most languages have stuck
to using PL/I standard types when passing arguments to external
programs. Languages that had non-standard types, such as BASIC,
was responsible for creating the proper descriptors and possibly
converting arguments during a call to a program in a different
language. In the relatively near future we are expecting more
languages with their own data types and more use of user_defined
types. There should be a recommended method for these languages
to talk to each other. First, there should be a standard way for
a caller to know that the callee is in a language that has
different data types. Second, there should be a well defined way
to translate argument lists, giving errors if types are
incompatible.
Alternatively we could restrict languages with their own data
types to calling only programs of the same language. This would
be hard for the dynamic linker to enforce and would probably be
unacceptable to many Multics users. This MTB is only introducing
the problem as a side-effect of choosing the direction of
extended data types. It should be discussed in greater detail in
another MTB.
NEW PASCAL SYMBOL NODE FORMAT
Object Oriented Approach
There is a new runtime symbol node format for Pascal. It might
be possible to use the existing format with extensions. For
example, if type = 58, the word before the symbol node could
contain the extended type code. However, there are several other
items to be added, so the end result would be quite complicated.
We have chosen to use a format that contains all the necessary
information in a straightforward way.
Multics Technical Bulletin MTB 632
The symbol node is referenced primarily by probe and stu_. These
are already quite complicated and would be harder to maintain if
they had to know about different formats. Instead, direct
knowledge of symbol node formats has been mostly removed from
them and put into the new program runtime_symbol_info_
(documented in Appendix C).
In addition to containing different items, the Pascal symbol node
will be organized in a new way. Adding the Pascal items to the
symbol node almost doubles its size. In addition, Pascal
programs will probably have more nodes than PL/I programs because
of the enumerated and user-defined types. In order to keep the
size under control, each Pascal symbol node will contain only
relevant items. Flags at the beginning of the node indicate
which items are included. This is likely to cut the size of the
symbol table (excluding the statement map) by at least 1/2 and
possibly by 2/3.
This condensed format has some disadvantages. It is not easily
referenced via PL/I and it takes longer to reference most items.
These should not be major problems. Symbol nodes are now usually
referenced via runtime_symbol_info_ and not directly in PL/I.
Most references occur during debugging, when performance is not
critical. In this case, it is felt that the time-space trade-off
should favor space.
Declaration
The declaration of the Pascal runtime symbol node is given as a
series of separate item declarations. No single node will
contain all the items. The header will always be present. The
other items to be included must be present in the order in which
they are documented.
dcl 1 pascal_symbol_node_header aligned based,
2 flags unaligned,
3 version_flag bit (1) unaligned, /* "0"b */
3 aligned bit (1) unaligned,
3 packed bit (1) unaligned,
3 in_with_block bit (1) unaligned,
3 name_next bit (1) unaligned,
3 base_type_info bit (1) unaligned,
3 address bit (1) unaligned,
3 father_brother bit (1) unaligned,
3 son_level bit (1) unaligned,
3 father_type_successor
bit (1) unaligned,
3 size bit (1) unaligned,
3 offset bit (1) unaligned,
3 subrange_limits bit (1) unaligned,
3 array_info bit (1) unaligned,
MTB 632 Multics Technical Bulletin
3 variant_info bit (1) unaligned,
3 pad bit (3) unaligned,
2 version fixed bin (17) unaligned,
2 type fixed bin (17) unaligned,
2 type_offset fixed bin (18) unsigned unaligned;
dcl 1 pascal_name_next aligned based,
2 name fixed bin (18) unsigned unaligned,
2 next_token fixed bin (18) unsigned unaligned;
dcl 1 pascal_base_type_info aligned based,
2 base_type fixed bin (17) unaligned,
2 base_type_offset fixed bin (18) unsigned unaligned;
dcl 1 pascal_address aligned based,
2 location fixed bin (18) unsigned unaligned,
2 class fixed bin (6) unsigned unaligned,
2 use_digit bit (1) unaligned,
2 units bit (2) unaligned,
2 offset_is_encoded bit (1) unaligned,
2 pad bit (8) unaligned;
dcl 1 pascal_father_brother aligned based,
2 father fixed bin (18) unsigned unaligned,
2 brother fixed bin (18) unsigned unaligned;
dcl 1 pascal_son_level aligned based,
2 son fixed bin (18) unsigned unaligned,
2 level fixed bin (6) unsigned unaligned,
2 pad bit (12) unaligned;
dcl 1 pascal_father_type_successor aligned based,
2 father_type fixed bin (17) unaligned,
2 successor fixed bin (18) unsigned unaligned;
dcl pascal_size fixed bin (35) based;
dcl pascal_offset fixed bin (35) based;
dcl 1 pascal_subrange_limits aligned based,
2 flags aligned,
3 lower_bound_is_encoded
bit (1) unaligned,
3 upper_bound_is_encoded
bit (1) unaligned,
3 pad bit (34) unaligned,
2 subrange_lower_bound
fixed bin (35),
2 subrange_upper_bound
fixed bin (35);
Multics Technical Bulletin MTB 632
dcl 1 pascal_array_info aligned based,
2 access_info aligned,
3 ndims fixed bin (6) unsigned unaligned,
3 use_digit fixed bin (1) unsigned unaligned,
3 array_units fixed bin (2) unsigned unaligned,
3 virtual_origin_is_encoded
bit (1) unaligned,
3 pad bit (26) unaligned,
2 virtual_origin fixed bin (35),
2 bounds (nd refer (pascal_array_info.access_info.ndims))
aligned,
3 lower fixed bin (35),
3 upper fixed bin (35),
3 multiplier fixed bin (35),
3 subscript_type fixed bin (17) unaligned,
3 subscript_type_offset
fixed bin (18) unsigned unaligned,
3 flags aligned,
4 lower_is_encoded
bit (1) unaligned,
4 upper_is_encoded
bit (1) unaligned,
4 multipler_is_encoded
bit (1) unaligned,
4 pad bit (33) unaligned;
dcl 1 pascal_variant_info aligned based,
2 number_of_variants
fixed bin (17) unaligned,
2 pad bit (18) unaligned,
2 first_value_in_set fixed bin (35) unaligned,
2 case (nvariants refer
(pascal_variant_info.number_of_variants)),
3 set_offset fixed bin (18) unsigned unaligned,
3 brother fixed bin (18) unsigned unaligned;
dcl 1 pascal_encoded_value aligned based,
2 code bit (6) unaligned,
2 (n1, n2) bit (6) unaligned,
2 n3 fixed bin (18) unsigned unaligned;
dcl nvariants fixed bin (17);
dcl nd fixed bin (6) unsigned;
New Storage Class
A new storage class has been defined. Storage class 11 is used
for constants whose value is not generated anywhere. The
location field contains the relative offset of the place where
the value is generated in the symbol section. This class is used
for some constants and enumerated type elements.
MTB 632 Multics Technical Bulletin
New Encoded Value Code
A new encoded value code has been defined. If code = 16, value
is the contents of the location described by the symbol node at
self-relative offset n3. n1 = "01"b3 if the value is signed; n1
= "00"b3 if the value is unsigned. n2 is the precision in bits
of the value.
This is used for subrange bounds which are previously defined
constants or enumerated type elements.
Relationship of Type Codes
With Pascal, it becomes necessary to describe types themselves in
the symbol table. The following table helps to show the
relationship between the type codes used by variables and those
used by types.
Multics Technical Bulletin MTB 632
type codes used for variables, corresponding type_offset and
record fields, constants, type codes used for types
subscript types and base types
(1) integer predefined (no type_offset)
(4) real "
(65) pascal char "
(66) pascal boolean "
(75) pascal text file "
(72) pascal enumerated type type_offset is the relative
instance offset of a symbol node with
type code enumerated type (70)
(74) pascal user defined type type_offset is the relative
instance offset of a symbol node with
one of the following type codes:
(73) pascal user_defined type
(used for arrays and subranges)
(67) pascal record file type
(64) pascal typed pointer type
(68) pascal record type
(69) pascal set type
Appendix B describes the contents of the symbol nodes for most of
the data types.
Variables Used Inside With Blocks
"With" statements create a new scope for record variable
identifiers. This, as in procedure scoping, should be reflected
in the symbol tree's block structure. Each "with" statement
should have its own runtime_block node, where "with a,b,c" is
treated as "with a do with b do with c do". Symbol names inside
the "with" block will all be relative to the name in the "with"
statement. Records used in "with" blocks cannot be fully
represented, in part because names in "with" statements can
contain variable subscripts. In order to have the complete name
to print out, a "with" statement's runtime_block node will
contain the identifier string given in the "with" statement.
This can be done compatibly as shown below.
The runtime_block will be changed in the following way to
indicate a "with" statement. The type field, which PL/I does not
set to meaningful values, will be redefined with the following
values:
"01"b3 external entry
"02"b3 non quick internal procedure
"03"b3 quick internal procedure
"04"b3 begin block
"05"b3 pascal with block
When type = "05"b3, two new fields are appended to the structure:
MTB 632 Multics Technical Bulletin
2 with_string fixed bin (18) unsigned unaligned,
2 real_level_1 fixed bin (18) unsigned unaligned
where
with_string
is a self-relative pointer to the ACC string that
duplicates the string in the source program's "with"
statement or the equivalent. This string is to be
used only by the probe symbol request. It is not
used when obtaining the location or printing the
value of a variable.
real_level_1
is a self-relative pointer to the level 1 node of the
original (complete) record type symbol
representation.
Variables used inside "with" blocks are addressed
differently from variables used elsewhere. The assumption is
that the compiler generates a temporary pointer to the base of
the sub-record. This pointer is then used to access variables
inside the scope of the "with" block. Therefore, these variables
are treated as based, with an encoded value giving the location
of the pointer.
Since probe may have to treat variables in "with" blocks
somewhat differently, the runtime_symbol nodes for all such
"level 1" variables should have the in_with_block flag set.
Multics Technical Bulletin MTB 632
APPENDIX A
New Data Type Representations
Pascal Typed Pointer Type (descriptor type 64)
A Pascal typed pointer type describes a packed or unpacked
pointer which can only be used with data described by the
type associated with the pointer. This is enforced by
software. A Pascal typed pointer datum actually has the
type user-defined type instance.
Pascal Char (descriptor type 65)
A Pascal char datum is a single character with a real,
fixed-point, binary, unsigned integer value between 0 and
127 inclusive.
A packed Pascal char datum occupies one 9-bit byte and is
aligned on a byte boundary.
An unpacked Pascal char datum occupies the rightmost 9-bit
byte of a word that is aligned on a word boundary. The
leftmost three bytes of the word are filled with zeroes.
Pascal Boolean (descriptor type 66)
A Pascal boolean datum has an integer value of 0 for FALSE
and 1 for TRUE.
A packed Pascal boolean datum occupies one byte and is
aligned on a byte boundary.
An unpacked Pascal boolean datum occupies one word and is
aligned on a word boundary.
Pascal Record File Type (descriptor type 67)
MTB 632 Multics Technical Bulletin
The Pascal record file type describes a type of file which
is an array of records. This type code is used only in
runtime symbol tables.
A Pascal record file datum actually has the type Pascal
user-defined type instance. It is represented by an
unpacked pointer to the Pascal record file status block.
The format of a record file status block is not defined as a
Multics standard.
Pascal Record Type (descriptor type 68)
The Pascal record type describes a datum which is similar to
a structure (descriptor type 17).
A packed member of a record is aligned on a 9-bit byte
boundary. This is not always the first unused byte. For
example, a 1-byte member between two 1-word members often
occupies the rightmost byte of the intervening word for
efficiency.
A Pascal record datum actually has the type Pascal
user-defined type instance.
Pascal Set Type (descriptor type 69)
The Pascal set type describes a datum which is a nonvarying
bit string whose length is equal to the number of elements
in the set. The maximum length is 288 bits (8 words). In
the following descriptions, L refers to the length in bits.
If 72 < L < 289, the datum is aligned on a double (even)
word boundary and occupies 8 words.
If 36 < L < 73, the datum is aligned on a double (even) word
boundary and occupies 2 words.
If the set is packed and 18 < L < 37, or if the set is
unpacked and 0 < L < 37, the datum is aligned on a word
boundary and occupies 1 word.
Multics Technical Bulletin MTB 632
If the set is packed and 9 < L < 19, the datum is aligned on
a half-word boundary and occupies 2 9-bit bytes.
If the set is packed and 0 < L < 10, the datum is aligned on
a 9-bit byte boundary and occupies one byte.
A Pascal set datum actually has the type Pascal user-defined
type instance.
Pascal Enumerated Type (descriptor type 70)
The Pascal enumerated type describes a datum which contains
one element of a set of symbolic values. The symbolic
values are represented by real, fixed-point, binary,
unsigned integers with values from 0 through n-1, where n is
the number of elements in the type.
An unpacked datum is aligned on a word boundary and occupies
1 word.
A packed datum is aligned on a half-word boundary, occupying
2 9-bit bytes, when n > 512. A packed datum is aligned on a
9-bit byte boundary, occupying 1 byte, when n <= 512.
This type code is used primarily in runtime symbol tables.
Data of Pascal enumerated types declared by the program
actually have the type Pascal enumerated type instance.
Pascal Enumerated Type Element (descriptor type 71)
A Pascal enumerated type element is one of the symbolic
values for a Pascal enumerated type. It is represented by a
real, fixed-point, binary, short, unsigned integer.
This type code is used only in runtime symbol tables.
Pascal Enumerated Type Instance (descriptor type 72)
A Pascal enumerated type instance is a datum of a Pascal
enumerated type. It is represented by a real, fixed-point,
binary, unsigned integer. The alignment and size of the
MTB 632 Multics Technical Bulletin
datum depend on the description of the Pascal enumerated
type and on the environment where it is declared (a field in
a packed record or element of a packed array is packed).
Pascal User Defined Type (descriptor type 73)
A Pascal user-defined type is a type defined by the user
either implicitly or explicitly as an array or subrange.
The description of such a type is contained in a runtime
symbol table node.
Pascal User Defined Type Instance (descriptor type 74)
A Pascal user-defined type instance is a datum of a Pascal
user-defined type.
Pascal Text File (descriptor type 75)
A Pascal text file is represented by an unpacked pointer to
a Pascal text file status block. The format of the text
file status block is not defined as a Multics standard.
Pascal Procedure Type (descriptor type 76)
The Pascal procedure type type code us used in the runtime
symbol table in conjunction with symbol nodes for internal,
exported and imported procedures (types 25, 26, 27). Symbol
nodes of this generic type are used to anchor descriptions
of the parameter lists. They are separated from their
associated procedure symbol nodes in order to facilitate
comparison of parameter lists.
Pascal Variable Formal Paramater (descriptor type 77)
The Pascal formal variable parameter type code is used in
the runtime symbol table to describe a procedure parameter
that is passed by reference.
Pascal Value Formal Parameter (descriptor type 78)
Multics Technical Bulletin MTB 632
The Pascal formal value parameter type code is used in the
runtime symbol table to describe a procedure parameter that
is passed by value.
Pascal Procedure Formal Parameter (descriptor type 79)
The Pascal formal parameter procedure parameter type code is
used in the runtime symbol table to describe a procedure
parameter that is itself a procedure or function.
Pascal Procedure Parameter (descriptor type 80)
A Pascal procedure parameter datum (always unpacked is
represented by a pair of unpacked pointers followed by a
real, fixed-point, binary, short, unpacked integer. The
pointers have the same meaning as for an entry datum (type
16). The integer is the offset in the pascal_operators_
transfer vector of the transfer to the entry operator to be
used for the procedure parameter.
MTB 632 Multics Technical Bulletin
APPENDIX B
Contents of Symbol Nodes
TYPE NODES
1 Integer or Char Subrange
pascal_symbol_node_header
flags set :
name_next if type has name
base_type_info
father_brother if type has name
subrange_limits
type = pascal user defined type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = integer or pascal char
base_type_offset = 0
pascal_father_brother if type has name
father (standard)
brother (standard)
pascal_subrange_limits
flags
lower_bound_is_encoded
upper_bound_is_encoded
subrange_lower_bound
subrange_upper_bound
Note:
If a bound is not encoded, it contains an integer
or Pascal char value.
An encoded value may be used if a previously declared
constant has been used to declare the type.
Example: T1 - 1..maxsize;
code = 16
n3 = relative offset to "maxsize" symbol node
Multics Technical Bulletin MTB 632
TYPE NODES
2 Array
pascal_symbol_node_header
flags set :
packed if array is packed
name_next if type has name
base_type_info
father_brother if type has name
array_info
type = pascal user defined type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = type code for elements of array
base_type_offset = relative offset of base-type node
pascal_father_brother (if type has name)
father (standard)
brother (standard)
pascal_size = size of elements of array
pascal_array_info
access_info
ndims
use_digit
array_units
virtual_origin_is_encoded
virtual_origin
bounds (nd refer
(pascal_array_info.access_info.ndims))
lower
upper
multiplier
subscript_type = type code for subscript
subscript_type_offset = relative offset of
subscript type node
flags
lower_is_encoded
upper_is_encoded
multiplier_is_encoded
Note:
MTB 632 Multics Technical Bulletin
Subscript type is zero if subscript is numeric and
not previously declared.
Example: array [1..10] of real ;
(Symbol node for 1..10 type is not created)
The virtual_origin field is not used when the array is
conformant, i.e. when bounds(1).flags.lower_is_encoded = "1"b.
In this case, the virtual origin is computed as
bounds (1) * multiplier (1).
Multics Technical Bulletin MTB 632
TYPE NODES
3 Enumerated Type Subrange
pascal_symbol_node_header
flags set :
name_next if type has name
base_type_info
father_brother if type has name
subrange_limits
type = pascal user defined type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = pascal enumerated type instance
base_type_offset = relative offset of node for
enumerated type
pascal_father_brother (if type has name)
father (standard)
brother (standard)
pascal_subrange_limits
flags
lower_bound_is_encoded = "1"b
upper_bound_is_encoded = "1"b
subrange_lower_bound
subrange_upper_bound
Note:
Bounds are encoded with code = 16 and
n3 = relative offset of the symbol node for an enumerated
type element.
MTB 632 Multics Technical Bulletin
TYPE NODES
4 Enumerated Type
pascal_symbol_node_header
flags set :
name_next if type has name
father_brother if type has name
son_level
type = pascal enumerated type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_father_brother if type has name
father (standard)
brother (standard)
pascal_son_level
son = relative offset of symbol node
for first constant of type
level = 0
Multics Technical Bulletin MTB 632
TYPE NODES
5 Typed Pointer Type
pascal_symbol_node_header
flags set :
name_next if type has name
base_type_info
father_brother if type has name
type = pascal typed pointer type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = type code for the referenced variable
(any type code allowed for a
Pascal variable)
base_type_offset = relative offset of base-type node
pascal_father_brother (if type has name)
father (standard)
brother (standard)
pascal_size = size corresponding to the type
of the referenced variable
MTB 632 Multics Technical Bulletin
TYPE NODES
6 Pascal Set Type
pascal_symbol_node_header
flags set :
name_next if type has name
base_type_info
father_brother if type has name
type = pascal set type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = type code for elements of set
base_type_offset = relative offset of base-type node
pascal_father_brother if type has name)
father (standard)
brother (standard)
Multics Technical Bulletin MTB 632
TYPE NODES
Pascal Record Type
pascal_symbol_node_header
flags set :
packed if record is packed
name_next if type has name
father_brother if type has name
son_level
type = pascal record type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_father_brother if type has name)
father (standard)
brother (standard)
pascal_son_level
son = relative offset of symbol node
for the first field
level = 1
MTB 632 Multics Technical Bulletin
TYPE NODES
8 Pascal Record File Type
pascal_symbol_node_header
flags set :
name_next if type has name
base_type_info
father_brother if type has name
type = pascal record file type
type_offset = 0
pascal_name_next (if type has name)
name (standard)
next_token (standard)
pascal_base_type_info
base_type = type of the elements of array
base_type_offset = relative offset of base-type node
pascal_father_brother if type has name)
father (standard)
brother (standard)
Multics Technical Bulletin MTB 632
TYPE NODES
9 Procedure Type
pascal_symbol_node_header
flags set :
base_type_info if it is a function
son_level
size if it is a function
type = pascal procedure type
type_offset = 0
pascal_base_type_info (if it is a function)
base_type = type of the returned value
base_type_offset = relative offset of base-type node
pascal_son_level
son = relative offset of symbol node
for the first formal parameter
if any; 0 if none
level = 0
pascal_size (if it is a function)
= size corresponding to the type of
the returned value
MTB 632 Multics Technical Bulletin
VARIABLE NODES
Variables
pascal_symbol_node_header
flags set :
name_next
address
father_brother
size
type = type code for the variable
type_offset = relative offset of type node
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location (standard)
class (standard)
units (standard)
pascal_father_brother
father (standard)
brother (standard)
pascal_size = size of the variable
corresponding to the type
Multics Technical Bulletin MTB 632
FIELD NODES
1 Field In a Record (Simple)
pascal_symbol_node_header
flags set :
name_next
address
father_brother
son_level
size
offset
type = type of the field
type_offset = relative offset of type node
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location = 0
class = 0
units (standard) (used for offset)
pascal_father_brother
father = relative offset of symbol node
for father record type
brother = relative offset of symbol node
for next field (0 if none)
pascal_son_level
son = 0
level = 2
pascal_size = size of the field corresponding to
the type code
pascal_offset = offset (in pascal_address.units)
of the field in the record
MTB 632 Multics Technical Bulletin
FIELD NODES
2 Field In a Record (Selector)
pascal_symbol_node_header
flags set :
name_next if field has name
address if field has name
father_brother
son_level
size
offset if field has name
variant_info
type = type of the field
type_offset = relative offset of type node
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location = 0
class = 0
units (standard - used for offset)
pascal_father_brother
father = relative offset of symbol node
for containing record
brother = 0
pascal_son_level
son = 0
level = 2
pascal_size (if field has name)
pascal_offset (if field has name
pascal_variant_info
number_of_variants
first_value_in_set
case (nvariants refer
(pascal_variant_info.number_of_variants)),
set_offset
brother
Multics Technical Bulletin MTB 632
Example: bignum = 1000..1003 ;
rec = record
case bignum of
1000 : ...
10002, 1003 : ...
1001 : ...
end ;
number_of_variants = 3 ;
first_value_in_set = 1000 ;
set string length = 4 bits
The selector field is logical and has no name and no place.
MTB 632 Multics Technical Bulletin
FIELD NODES
3 Field Accessed In a WITH Block
pascal_symbol_node_header
flags set :
in_with_block
name_next
address
father_brother
son_level
size
offset
type = type of the field
type_offset = 0
pascal_name_next
name
next_token
pascal_address
location (standard)
class (standard)
units (standard)
pascal_father_brother
father = relative offset to with block node
brother = relative offset to brother field node
in with block
pascal_size
pascal_offset (standard)
Multics Technical Bulletin MTB 632
CONSTANT NODES
1 Integer, Real and Char Constants
pascal_symbol_node_header
flags set :
name_next
address
father_brother
size
type = integer, real or pascal char
type_offset = 0
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location (standard)
class (standard)
pascal_father_brother
father (standard)
brother (standard)
pascal_size = size in bits (for char)
or precision (for integer and real)
of generated constant
MTB 632 Multics Technical Bulletin
CONSTANT NODES
2 Enumerated Type Element
pascal_symbol_node_header
flags set :
name_next
address
father_brother
father_type_successor
size
type = pascal enumerated type element
type_offset = 0
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location (standard)
class (standard) (= 11)
pascal_father_brother
father (standard)
brother (standard)
pascal_father_type_successor
father_type = relative offset of node for
containing enumerated type
successor = relative offset of symbol node for
next constant in containing type
pascal_size = size in bits of internal code
Multics Technical Bulletin MTB 632
CONSTANT NODES
3 String Constant
pascal_symbol_node_header
flags set :
name_next
address
father_brother
size
type = pascal user defined type instance
type_offset = relative offset of symbol node for type
"packed array [1..nbr_of_chars] of char"
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location (standard)
class (standard)
pascal_father_brother
father (standard)
brother (standard)
pascal_size = length in bits (9 * nbr_of_chars)
MTB 632 Multics Technical Bulletin
LABEL NODES
Label
pascal_symbol_node_header
flags set :
name_next
address
father_brother
type = label
type_offset = 0
pascal_name_next
name (standard) (like FORTRAN labels)
next_token (standard)
pascal_address
location (standard)
class (standard)
pascal_father_brother
father (standard)
brother (standard)
Multics Technical Bulletin MTB 632
PROCEDURE NODES
Procedure
pascal_symbol_node_header
flags set :
name_next
address
father_brother
type = pascal internal procedure
or pascal imported procedure
or pascal exportable procedure
or pascal procedure parameter
type_offset = relative offset of a procedure
type symbol node
pascal_name_next
name (standard)
next_token (standard)
pascal_address
location (standard)
class (standard)
pascal_father_brother
father (standard)
brother (standard)
pascal_size (only for pascal procedure parameter)
MTB 632 Multics Technical Bulletin
FORMAL PARAMETER NODES
1 Variables
pascal_symbol_node_header
flags set :
name_next
base_type_info
father_brother
type = pascal variable formal parameter
or pascal value formal parameter
type_offset = 0
pascal_name_next
name = relative offset of acc string
next_token = 0
pascal_base_type_info
base_type = type code for the parameter
base_type_offset = relative offset of base-type node
pascal_father_brother
father relative offset of procedure type
symbol node
brother relative offset of node for the
next formal parameter; 0 if last
Multics Technical Bulletin MTB 632
FORMAL PARAMETER NODES
2 Entries
pascal_symbol_node_header
flags set :
name_next
father_brother
type = pascal procedure formal parameter
type_offset = relative offset of a procedure
type symbol node
pascal_name_next
name relative offset of acc string
next_token = 0
pascal_father_brother
father relative offset of a procedure
type symbol node
brother relative offset of node for the
next formal parameter; 0 if last
MTB 632 Multics Technical Bulletin
APPENDIX C
runtime_symbol_info_
Attached is the documentation for runtime_symbol_info_.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
NAME: RUNTIME_SYMBOL_INFO_
This subroutine's various entry points return runtime information
about program variables (address, type, etc.) for programs
compiled with symbol tables (-table). Declarations for the entry
points and the structures they return can be found in the include
file runtime_symbol_info_.incl.pl1. Most entry points take a
pointer (symbol_ptr) to a symbol node, which can be obtained by
calling stu_$find_runtime_symbol. Rather than return error
codes, these entry points return null pointers or zero fields in
their structures if the symbol node does not contain the
requested information. Also see the various stu_ entry points
for additional information about program variables and text.
WARNING:
Use of these subroutines requires a good understanding of the
symbol table structures generated by translators. For example,
given a Pascal symbol "foo" declared variable of type packed
array [1..10] of char, runtime_symbol_info_ does not return any
useful information because this information resides in the symbol
node for the TYPE of "foo".
ENTRY: RUNTIME_SYMBOL_INFO_$ADDRESS
This entry point returns information about the location of a
symbol at runtime.
USAGE
declare runtime_symbol_info_$address entry (pointer, pointer);
call runtime_symbol_info_$address (symbol_ptr, info_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
info_ptr
is a pointer to a user-allocated structure to be filled in by
the call. This structure, called runtime_address_info, is
described under "Notes" below.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
NOTES
Information is returned in the following structure, declared in
the include file runtime_symbol_info_.incl.pl1:
dcl 1 runtime_address_info aligned based,
2 location fixed bin (18) unsigned unaligned,
2 class fixed bin (6) unsigned unaligned,
2 use_digit fixed bin (1) unsigned unaligned,
2 units fixed bin (2) unsigned unaligned,
2 offset_is_encoded bit (1) unaligned,
2 pad bit (8) unaligned,
2 offset fixed bin (35);
STRUCTURE ELEMENTS
location
is the offset of the data within the storage class specified
by the next field.
class
is the storage class:
0 No address information is available for this symbol.
1 - 15 See the symbol table documentation in the Multics Reference Manual.
use_digit
is "1"b to indicate that units are digits if units = 3.
units
gives the unit of storage:
0 word 36 bits
1 bit 1 bit
2 byte 9 bits
3 half-word/digit 18 / 4.5 bits
offset_is_encoded
is "1"b if the address is represented as an encoded offset in
the next field. Encoded values, described in the symbol table
documentation in the Reference Manual, are interpreted by
stu_$decode_runtime_value_extended.
offset
is the offset of the start of the identifier with respect to
the address specified by location and class. It is encoded if
offset_is_encoded="1"b.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
ENTRY: RUNTIME_SYMBOL_INFO_$ARRAY
This entry point returns information about array storage
allocation.
USAGE
declare runtime_symbol_info_$array entry (pointer, pointer);
call runtime_symbol_info_$array (symbol_ptr, info_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
info_ptr
is a pointer to a user-allocated structure to be filled in by
the call. This structure, called runtime_array_info, is
described under "Notes" below.
NOTES
Information is returned in the following structure, declared in
the include file runtime_symbol_info_.incl.pl1:
dcl 1 runtime_array_info aligned based,
2 access_info aligned,
3 ndims fixed bin (6) unsigned unaligned,
3 use_digit fixed bin (1) unsigned unaligned,
3 array_units fixed bin (2) unsigned unaligned,
3 virtual_origin_is_encoded
bit (1) unaligned,
3 pad bit (26) unaligned,
2 virtual_origin fixed bin (35),
2 bounds (16) aligned,
3 flags aligned,
4 lower_is_encoded bit (1) unaligned,
4 upper_is_encoded bit (1) unaligned,
4 multiplier_is_encoded bit (1) unaligned,
4 pad bit (33) unaligned,
3 lower fixed bin (35),
3 upper fixed bin (35),
3 multiplier fixed bin (35),
3 subscript_type fixed bin (35),
3 subscript_type_addr ptr;
STRUCTURE ELEMENTS
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
ndims
is the number of dimensions in the array (eg., 2 => N x M
array). If this value is zero, the symbol node does not
contain array information and the rest of the information in
the structure is meaningless.
use_digit
is "1"b to indicate that units are digits if array_units = 3.
array_units
gives the unit of storage:
0 word 36 bits
1 bit 1 bit
2 byte 9 bits
3 half-word/digit 18 / 4.5 bits
virtual_origin_is_encoded
is "1"b if the origin is represented as an encoded value in
the next field. Encoded values are interpreted by
stu_$decode_runtime_value_extended.
virtual_origin
is the virtual origin of the array, in units given by
array_units. Its value should be subtracted from the base
address specified by the address location and class. This
value is meaningless for Pascal conformant arrays, for which
the origin is equal to low(1) * multiplier(1).
bounds
gives, for each dimension, information describing the bounds
and subscript.
lower_is_encoded
is "1"b if lower is an encoded value.
upper_is_encoded
is "1"b if upper is an encoded value.
multiplier_is_encoded
is "1"b if multiplier is an encoded value.
lower
is the lower bound of this dimension.
upper
is the upper bound of this dimension.
multiplier
is the size of an element in units given by array_units.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
subscript_type
for a Pascal array, this is the type of subscript allowed for
this dimension.
subscript_type_addr
for a Pascal array, this is a pointer to a Pascal type node
describing the type of subscript allowed for this dimension.
It is null if there is no type node.
ENTRY: RUNTIME_SYMBOL_INFO_$ARRAY_DIMS
This entry point returns the number of dimensions of an array.
It returns null if the symbol has no dimensions.
USAGE
declare runtime_symbol_info_$array_dims entry (pointer) returns
(fixed bin);
n_dims = runtime_symbol_info_$array_dims (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$BROTHER
This entry point, given a pointer to a symbol node for an
aggregate component, returns a pointer to the next component at
the same level or null if this is the last component at this
level of the aggregate. Given a pointer to a formal parameter,
it returns a pointer to the node for the next parameter, or null
if there is no next parameter. Given a pointer to any other
symbol node whose level is <= 1 (non_aggregate or top-level
structure) and which has a name, returns a pointer to the next
element on the list of symbol nodes ordered alphabetically by
size. It returns null if there is no next symbol.
USAGE
declare runtime_symbol_info_$brother entry (pointer) returns
(pointer);
brother_ptr = runtime_symbol_info_$brother (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
ENTRY: RUNTIME_SYMBOL_INFO_$FATHER
This entry point, given a pointer to a symbol node for an
aggregate component, returns a pointer to the symbol node for its
parent aggregate. Given a pointer to a symbol node whose level
is <= 1 and which has a name, returns a pointer to the runtime
block node that represents the block in which the identifier is
declared. It returns null if father = 0 or if there is no father
field.
USAGE
declare runtime_symbol_info_$father entry (pointer) returns
(pointer);
father_ptr = runtime_symbol_info_$father (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$FATHER_TYPE
This entry point, given a pointer to a symbol node for a Pascal
enumerated type element, returns a pointer to the symbol node for
the parent type. Otherwise, it returns null.
USAGE
declare runtime_symbol_info_$father_type entry (pointer) returns
(pointer);
father_type_ptr = runtime_symbol_info_$father_type (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$LEVEL
This entry point, given a pointer to a symbol node for an
aggregate component, returns the level number of the component in
the aggregate or zero if the symbol is not an aggregate
component. Fields in a Pascal "with" block are at level 0.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
USAGE
declare runtime_symbol_info_$level entry (pointer) returns (fixed
bin);
level_number = runtime_symbol_info_$level (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$N_VARIANTS
This entry point, given a pointer to a symbol node for a tag
field in a Pascal record, returns the number of case variants for
the field. It returns 0 if the symbol is not a tag field.
USAGE
declare runtime_symbol_info_$n_variants entry (pointer) returns
(fixed bin);
n_variants = runtime_symbol_info_$n_variants (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$NAME
This entry point, given a pointer to a symbol node, returns a
pointer to the symbol's name in packed form (see "Notes" below).
It returns null if there is no name.
USAGE
declare runtime_symbol_info_$name entry (pointer) returns
(pointer);
name_string = runtime_symbol_info_$name (symbol_ptr) ->
acc.string;
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
NOTES
The variable acc.string is declared in the include file
acc.incl.pl1:
dcl 1 acc based aligned,
2 num_chars fixed bin (9) unsigned unaligned,
2 string char (0 refer (acc.num_chars)) unaligned;
ENTRY: RUNTIME_SYMBOL_INFO_$NEXT
This entry point, given a pointer to a symbol node, returns a
pointer to the symbol node for the next identifier having the
same name as the current identifier. It returns null if there is
no name or if there are no more identifiers with the same name.
USAGE
declare runtime_symbol_info_$next entry (pointer) returns
(pointer);
next_symbol_ptr = runtime_symbol_info_$next (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$SON
This entry point, given a pointer to a symbol node for an
aggregate, returns a pointer to the symbol node for the
aggregate's first component. Given a pointer to a symbol node
for a procedure, it returns a pointer to the symbol node for the
first formal parameter. Given a pointer to a symbol node for an
enumerated type, it returns a pointer to the symbol node for the
first element of the type. Otherwise, it returns null.
USAGE
declare runtime_symbol_info_$son entry (pointer) returns
(pointer);
son_ptr = runtime_symbol_info_$son (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
ENTRY: RUNTIME_SYMBOL_INFO_$SUCCESSOR
This entry point, given a pointer to a symbol node for a Pascal
enumerated type element, returns a pointer to the symbol node for
the next element in the set of enumerated values for the type, or
null if there is no next element or no successor field.
USAGE
declare runtime_symbol_info_$successor entry (pointer) returns
(pointer);
successor_ptr = runtime_symbol_info_$successor (symbol_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
ENTRY: RUNTIME_SYMBOL_INFO_$TYPE
This entry point returns information about the data type of a
symbol.
USAGE
declare runtime_symbol_info_$type entry (pointer, pointer);
call runtime_symbol_info_$type (symbol_ptr, info_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
info_ptr
is a pointer to a user-allocated structure to be filled in by
the call. This structure, called runtime_type_info, is
described under "Notes" below.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
NOTES
Information is returned in the following structure, declared in
the include file runtime_symbol_info_.incl.pl1:
dcl 1 runtime_type_info aligned based,
2 flags,
3 aligned bit (1) unaligned,
3 packed bit (1) unaligned,
3 size_is_encoded bit (1) unaligned,
3 pad bit (25) unaligned,
2 scale fixed bin (7) unaligned,
2 (type, base_type) fixed bin (18) unsigned unaligned,
2 (type_addr, base_type_addr)
ptr,
2 size fixed bin (35);
STRUCTURE ELEMENTS
aligned
is "1"b if the value is aligned. The meaning of alignment
depends on the type. Refer to the Reference Manual's section
on the runtime symbol table.
packed
is "1"b if the value is packed. Refer to the Reference
Manual.
size_is_encoded
is "1"b if size is represented as an encoded value. Encoded
values are interpreted by stu_$decode_runtime_value_extended.
scale
is the scale factor for arithmetic values. Refer to the
Reference Manual.
type
is the type of the symbol. The defined types are declared in
the include file std_descriptor_types.incl.pl1.
base_type
when not equal to 0, is used in Pascal type description nodes
in the following cases: For subranges, it is either integer,
Pascal char, or Pascal enumerated type instance. For arrays,
sets, and record files, it is the type of the elements. For
typed pointers, it is the type of the referenced variable.
For function procedure types, it is the type of the return
value. For other procedure types, it is null.
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
type_addr
for Pascal user-defined and enumerated type variables,
constants, record fields, procedure types, subscript types and
base types, this is a pointer to a symbol node for the type
that the symbol belongs to. Otherwise, it is null.
base_type_addr
is a pointer to a symbol node describing base_type, when
base_type itself is neither 0 nor a simple type. Otherwise,
it is null.
size
is the arithmetic precision, string size, or area size of the
value. Refer to the Reference Manual.
ENTRY: RUNTIME_SYMBOL_INFO_$VARIANT
This entry point, given a pointer to a symbol node for a Pascal
record field with case variants, returns information describing
the variants. If the symbol is not a Pascal symbol,
number_of_variants is returned as 0 and the rest of the
information is invalid.
USAGE
declare runtime_symbol_info_$variant entry (pointer, pointer);
call runtime_symbol_info_$variant (symbol_ptr, info_ptr);
ARGUMENTS
symbol_ptr
is a pointer to a symbol node. (Input)
info_ptr
is a pointer to a user-allocated structure to be fille din by
the call. This structure, called runtime_variant_info, is
described under "Notes" below.
NOTES
Information is returned in the following structure, declared in
the include file runtime_symbol_info_.incl.pl1:
dcl 1 runtime_variant_info aligned based,
2 number_of_variants fixed bin,
2 first_value_in_set fixed bin (35),
2 case (n_variants),
3 set_addr ptr,
3 brother_addr ptr;
____________________ ____________________
runtime_symbol_info_ runtime_symbol_info_
____________________ ____________________
STRUCTURE ELEMENTS
number_of_variants
is the number of variants if the symbol node is for a Pascal
record tag field. Otherwise, it is null.
first_value_in_set
is the lowest value used to select a variant.
case
contains information for a particular variant.
set_addr
is a pointer to a bit string that specifies the cases of the
variant. The bit string represents a set (one bit per set
element) whose base type is the type of the symbol node
pointed to by symbol_ptr. The first bit corresponds to
first_value_in_set.
brother_addr
is a pointer to the first field of the variant part.