This information can be passed to print (and other external predefined routines) as well as the values. This enables print to correctly print out the value.
Some of this information is also passed to the linker program = directions for storing variables, procedures, arrays. We shall look at these "descriptors" but first the linker.
The link accepts as input, the output of one of the computer's translators or compilers in order to produce an executable version of your program. The compiler output, known as an object module or relocatable binary module, contains users programs plus additional information necessary for the linking of separately compiled modules. Most object modules contain relocatable code so that the modules position in memory can be determined by the linker.
The user benefits by not having to worry where one module ends and another starts. User can also code the modules and not worry about where it is put. When moving the relocatable code in memory to the place where it will execute, the linker adjusts all relocatable addresses, in the code to the absolute addresses. Linkage between modules is accomplished through symbolic addresses. By including symbolic addresses, the user is delaying assigning an actual value until load time.
By linking these modules, the linker provides communication between independantly compiled modules. When finished satisfying all these symbolic addresses, your program is ready to run.
NOTE: The relocation done by the linker has nothing to do with relocation of your code by segmentation or paging. This is yet another level of address trans- lation, but it is the same each time your program is Executed.
TABLE 2 shows the information which is required in general to describe an object. This block of information is called a descriptor and is created in the declaration phase of syntax analysis. In case of PL0 what information was created?
TABLE = record
name of identifier
Val if constant or
address and level
= scope of procedure or variable
end
When is it created?
The only declaration (in PL0) is of const, var, and procedures
and these occur as the first things tested within block.
Therefore when it comes to process statement all descriptors
must be defined.
Forward declarations of procedures must be used (if needed)
and must give number, order and type of parameters since
these descriptors must also be filled in.
DESCRIPTOR of procedure will contain a pointer to descriptor
for each of its parameters. This descriptor will also be
accessible via the entry for the name of the parameter.
The "kind" of object in Java is
(variable, array, procedure, constant, function, label, set,
packed-array, record, pointer, file, std-proc, std-function).
In simple languages such as FORTRAN-66 and BASIC, where the "type" is one of several fixed types; i.e. INTEGER, REAL, LOGICAL; The "type" field may be a simple enumerated type, i.e.
Since some languages allow a user to create his/her own
types, the "type" field has to be a pointer to a descriptor which
indicates the user defined type. We could emulate types complex
and double precision with user-defined types. But we still have
to process complex in some manner
i.e. var x,y,z: complex /* some predefined type */
:
zx*y /* not legal since not allowed type */
An example of typical layout:
ptr_to_node = node
node = record
info:integer
fptr:ptr_to_node
bptr:ptr_to_node
end
Example: {
char a;
a = 1;
}
Once the syntax analysis has been done, the information in
the descriptors is crucial to check for TYPEing errors, and the
like and for code generation.
Example: x = y
call EXPRESSION( ) to get information re x;
similarly call EXPRESSION ( ) re y.
if(x.type in [inttype, booltype, chartype, realtype])
and (x.type=y.type) then /* OK */
else /* TYPE conflict of OPERANDS */
char a;
{
a = b;
}