/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)printsym.c 1.2 %G%";
* Printing of symbolic information.
* Return a pointer to the string for the name of the class that
* the given symbol belongs to.
private String clname
[] = {
"bad use", "constant", "type", "variable", "array", "fileptr",
"record", "field", "procedure", "function", "funcvar",
"ref", "pointer", "file", "set", "range", "label", "withptr",
"scalar", "string", "program", "improper", "variant",
"procparam", "funcparam", "module", "typeref", "tag"
public String
classname(s
)
return clname
[ord(s
->class)];
* Note the entry of the given block, unless it's the main program.
printf("\nentering %s %s\n", classname(s
), symname(s
));
* Note the exit of the given block
printf("leaving %s %s\n\n", classname(s
), symname(s
));
* Note the call of s from t.
printf("calling %s", symname(s
));
printf(" from %s %s\n", classname(t
), symname(t
));
* Note the return from s. If s is a function, print the value
* it is returning. This is somewhat painful, since the function
* has actually just returned.
isindirect
= (Boolean
) (t
->class == RECORD
or t
->class == VARNT
);
pushretval(len
, isindirect
);
printf("(value too large) ");
printf("from %s\n", symname(s
));
* Print the values of the parameters of the given procedure or function.
* The frame distinguishes recursive instances of a procedure.
public printparams(f
, frame
)
if (param
!= nil
or n
> 0) {
s
= size(param
) div
sizeof(Word
);
printf("0x%x", argn(n
- m
, frame
));
* Test if a symbol should be printed. We don't print files,
* for example, simply because there's no good way to do it.
* The symbol must be within the given function.
public Boolean
should_print(s
)
t
!= nil
and t
->class != FILET
and t
->class != SET
* Print the name and value of a variable.
if (isambiguous(s
) and ismodule(container(s
))) {
printf("%s = ", symname(s
));
rpush(address(s
, frame
), sizeof(Address
));
addr
= address(s
, frame
);
printf("*** expression too large ***");
* Print out the name of a symbol.
} else if (isredirected() or isambiguous(s
)) {
fprintf(f
, "%s", symname(s
));
* Print the fully specified variable that is described by the given identifer.
printouter(f
, container(s
));
fprintf(f
, "%s", symname(s
));
* Print the fully qualified name of each symbol that has the same name
public printwhereis(f
, s
)
if (outer
!= nil
and outer
!= program
) {
fprintf(f
, "%s.", symname(s
));
(*language_op(s
->language
, L_PRINTDECL
))(s
);
* Straight dump of symbol information.
printf("name\t%s\n", symname(s
));
printf("lang\t%s\n", language_name(s
->language
));
printf("level\t%d\n", s
->level
);
printf("class\t%s\n", classname(s
));
printf("type\t0x%x", s
->type
);
if (s
->type
!= nil
and s
->type
->name
!= nil
) {
printf(" (%s)", symname(s
->type
));
printf("\nchain\t0x%x", s
->chain
);
if (s
->chain
!= nil
and s
->chain
->name
!= nil
) {
printf(" (%s)", symname(s
->chain
));
printf("\nblock\t0x%x", s
->block
);
if (s
->block
->name
!= nil
) {
printname(stdout
, s
->block
);
printf("address\t0x%x\n", s
->symvalue
.offset
);
printf("offset\t%d\n", s
->symvalue
.offset
);
printf("size\t%d\n", s
->symvalue
.offset
);
printf("offset\t%d\n", s
->symvalue
.field
.offset
);
printf("size\t%d\n", s
->symvalue
.field
.length
);
printf("address\t0x%x\n", s
->symvalue
.funcv
.beginaddr
);
printf("lower\t%d\n", s
->symvalue
.rangev
.lower
);
printf("upper\t%d\n", s
->symvalue
.rangev
.upper
);
* Print out the value on top of the stack according to the given type.
printf("%s", symname(s
));
if (t
->language
== nil
) {
error("unknown language");
(*language_op(t
->language
, L_PRINTVAL
))(t
);
* Print out the value of a record, field by field.
error("record has no fields");
* Print out a field, first printing out other fields.
* This is done because the fields are chained together backwards.
printf("%s = ", symname(s
));
sp
+= ((s
->symvalue
.field
.offset div BITSPERBYTE
) + size(s
->type
));
* Print out the contents of an array.
* Haven't quite figured out what the best format is.
* This is rather inefficient.
* The "2*elsize" is there since "printval" drops the stack by elsize.
if (eltype
->class == RECORD
or eltype
->class == ARRAY
or
eltype
->class == VARNT
) {
for (sp
+= elsize
; sp
<= savesp
; sp
+= 2*elsize
) {
if (sp
- elsize
!= newsp
) {
* Print out the value of a real number in Pascal notation.
* This is, unfortunately, different than what one gets
} else if (buf
[0] == '-' and buf
[1] == '.') {
if (index(buf
, '.') == nil
) {
* Print out a character using ^? notation for unprintables.
} else if (c
> 0 and c
< ' ') {